Leetcode 1306. 跳跃游戏 III
2019年的最后一天了,善始善终,上次报名的第169场Leetcode竞赛忘记参加了,那天上午干啥了???
然后补做了一下那个题目,还是挺简单的,下面做一下笔记和解题思路。
第一题:
1304. 和为零的N个唯一整数
给你一个整数 n
,请你返回 任意 一个由 n
个 各不相同 的整数组成的数组,并且这 n
个数相加和为 0
。
示例 1:
输入:n = 5 输出:[-7,-1,1,3,4] 解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。
思路:
由于(+x)+(-x)和为0,即互为相反数的两个值相加即可。
给定的n值有奇数偶数之分,是否包含元素0,如果奇数,则需要包含0,偶数去掉0,即可。
代码如下:
1 class Solution { 2 public: 3 vector<int> sumZero(int n) { 4 vector<int> res; 5 //从-n/2 到 n/2 依次存入结果集即可 6 for(int i=-n/2;i<=n/2;i++) 7 { 8 if(i==0 && n%2==0) 9 continue; 10 res.push_back(i); 11 } 12 return res; 13 } 14 };
第二题:
1305. 两棵二叉搜索树中的所有元素
给你 root1
和 root2
这两棵二叉搜索树。
请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。.
思路:
最简单最直接的方法,即将两棵树进行遍历,存入一个vector中,然后排序即可,(这里我们使用先序遍历方法)
代码如下:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> getAllElements(TreeNode* root1, TreeNode* root2) { 13 vector<int> res; 14 //遍历两棵树,节点存入res中去 15 dfs(root1,res); 16 dfs(root2,res); 17 sort(res.begin(),res.end()); 18 return res; 19 } 20 21 void dfs(TreeNode* root,vector<int> &res) 22 { 23 //先序遍历 24 if(root==nullptr) 25 return; 26 res.push_back(root->val); 27 dfs(root->left,res); 28 dfs(root->right,res); 29 } 30 };
第三题:
这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。
请你判断自己是否能够跳到对应元素值为 0 的 任意 下标处。
注意,不管是什么情况下,你都无法跳到数组之外。
示例 1:
输入:arr = [4,2,3,0,3,1,2], start = 5
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 5 -> 下标 4 -> 下标 1 -> 下标 3
下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
思路:
我们假设从start位置开始出发,有两条路可以走,要么左,要么右,所走的步长是arr[start],下一步的位置为start+arr[start]或者start-arr[start],对于新的位置有如下几种情况:
1. 向右走超过了数组的最大范围
2. 向左走超多了数组的最小范围
3. 访问了已经访问过的位置,即从第一次访该位置,走了一圈又回到了原点(这点儿很重要,避免死循环)
对于以上情况,我们将终止行走,认为此路不通。
经过分析,好像题目类似于二叉树的搜索,搜索一条路径,使得终止节点上的数为0,首先想到的是用栈来模拟回溯操作,但这样频繁的出栈和入栈,干脆递归好了~~~
除了以上几种情况,我们将对该start结点的值进行访问,看是否为0,然后以start - arr[start] 和 start - arr[start] 为新的开始结点,进行递归操作。
申请一个vector<int> flag,用来记录该位置是否被访问过~
代码如下:
1 class Solution { 2 public: 3 bool canReach(vector<int>& arr, int start) { 4 //类似于树的遍历,递归实现,start认为是根节点 5 vector<int> flag; 6 flag.resize(arr.size(),0); 7 dfs(arr,start,flag); 8 return res; 9 } 10 11 void dfs(vector<int> arr,int pos,vector<int>& flag){ 12 //先序遍历 13 if(pos<0 || pos>=arr.size() || flag[pos]==1) 14 return; 15 if(arr[pos]==0) 16 { 17 res=true; 18 return; 19 } 20 flag[pos]=1; //置为已被访问 21 dfs(arr,pos-arr[pos],flag); 22 dfs(arr,pos+arr[pos],flag); 23 } 24 bool res=false; 25 };
看结果,这。。。也太刺激了吧~~~(●´∀`●)
最后一题还没做~