144. 二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void PreOrder(TreeNode *root,vector<int>& num){
if(root == nullptr){ //原来用void才可以return ;因为void的return就是空的
return ;
}
num.push_back(root->val);
PreOrder(root->left,num);
PreOrder(root->right,num);
}
vector<int> preorderTraversal(TreeNode *root) {
vector<int> num;
PreOrder(root,num);
return num;
}
};
心得
注意:
- 我一开始直接对
preorderTraversal
这个函数做了递归。但我真是个笨蛋,我在preorderTraversal里生成的num,那每次递归都新生成一个num,最后可不是num是空的。因为每次都是新生成的 - 递归函数
PreOrder
里记得把num的引用也传进去,不然没法对num做修改 - 只有
void
声明才可以用return ;
这种形式,因为void不返回值
26. 删除有序数组中的重复项
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = […]; // 输入数组
int[] expectedNums = […]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
提示:
0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 升序 排列
代码
class Solution {
public:
//总结:一定要在纸上把具体的细节整理出来。
//这道题想到了快慢指针后,还是要用纸把具体的快慢指针移动的过程模拟出来
//光用脑子想是一定想不出来的
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if(n == 0){
return 0; //一定要有判断特殊情况的意识
}
//虽然说是快慢指针,实际上就是制造两个下标即可
int fast = 1; //范围一定要标清楚,避免越界。这里fast设成从1开始
int slow = 1; //slow也要从1开始,不然一开始的那个数读不进去
while(fast < n){
if(nums[fast]>nums[fast-1]){
nums[slow] = nums[fast];
slow++; //slow++一定要写在if里面,这就是没写在纸上出的错
}
fast++;
}
return slow;
}
};
总结
- 一定要在纸上把具体的细节整理出来。
- 这道题想到了快慢指针后,还是要用纸把具体的快慢指针移动的过程模拟出来
- 光用脑子想是一定想不出来的
- 一定要有判断特殊情况的意识
- 虽然说是快慢指针,实际上就是制造两个下标即可
- 范围一定要标清楚,避免越界。这里fast设成从1开始;slow也要从1开始,不然一开始的那个数读不进去
- slow++一定要写在if里面,这就是没写在纸上,模拟逻辑没理清楚出的错
明日做题:
27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
代码
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int fast = 0;
int slow = 0;
while(fast < n){ //遍历可以用for循环也可以用while循环
if(nums[fast]!=val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
心得
最重要的还是在纸上写出来,循环可以用for也可以用while,分情况来写。快慢指针原地修改这种方法很常见了
463. 岛屿的周长
给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
示例 1:
输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16
解释:它的周长是上面图片中的 16 个黄色的边
示例 2:
输入:grid = [[1]]
输出:4
示例 3:
输入:grid = [[1,0]]
输出:4
提示:
row == grid.length
col == grid[i].length
1 <= row, col <= 100
grid[i][j] 为 0 或 1