zoukankan      html  css  js  c++  java
  • 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 };

     第三题:

       1306. 跳跃游戏 III

      这里有一个非负整数数组 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 };

    看结果,这。。。也太刺激了吧~~~(●´∀`●)

     最后一题还没做~

  • 相关阅读:
    自定义协议的注册及程序示例转载
    在windows phone 中使用原生代码开发程序(native code)
    C# 操作系统防火墙转载
    WP7Windows Phone的Isolated Storage Explorer使用指南
    如何让wp7真机调试时候保持屏幕高亮不锁屏
    利用C#检测证书是否存在,并安装证书
    WPF设置附加属性的值
    wpf值转换器IValueConverter转载
    ADO.NET一些内幕
    怎样将数据库中所有表中含有numeric(18,2)字段改成numeric(18,10)及将float改成numeric
  • 原文地址:https://www.cnblogs.com/cnyulei/p/12123123.html
Copyright © 2011-2022 走看看