跟我打卡LeetCode 61旋转链表&62不同路径&63不同路径 II

原创公众号:bigsai
关注后回复进群即可加入力扣打卡群,欢迎划水。近期打卡:
LeetCode 49字母异位词分组&50pow(x,n)&51八皇后
LeetCode打卡 52八皇后Ⅱ&53最大子序和&54螺旋矩阵
LeetCode 55跳跃游戏&56合并区间&57插入区间
跟我打卡LeetCode 58最后一个单词长度&59螺旋矩阵Ⅱ&60排列序列

旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL

示例 2:

输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL

分析
本题的话就是题意比较清晰,就是旋转链表将链表进行右移动k个。

但是具体的处理上可能存在时间复杂度的差距,比如你可以第一次遍历到结尾,然后构成一个循环链表不停遍历找到合适的位置。或者先遍历一次到尾,然后再找到需要移动的位置去进行操作,但是这样都避免不了循环两次。

那本题采用什么方法呢?使用快慢指针,快指针先走k步,然后快慢指针一起走,一直到快指针走到尾。 执行以下操作即可:

  • fast.next=head
  • ListNode team=slow
  • slow.next=null
  • return team

在这里插入图片描述
在这里插入图片描述

但是过程可能没那么顺畅,很可能k比整个链表的长度还大,所以可能k没跑完就遍历结束了,这种情况也不用担心,当fast到底的时候可以通过一次计算算出真实有效的移动位数。比如如果链表长10让你右移59,69,79这些和移动9次是一样的,所以只需要slow再次移动到真实有效的地方即可。
在这里插入图片描述

实现的代码为:

 public ListNode rotateRight(ListNode head, int k) {
      if(k==0||head==null)return head;
       ListNode fast=head;
       ListNode slow=head;
      
       for(int i=0;i<k;i++)
       {            
           if(fast.next==null)//说明超出范围了 但是此时知道最大长度了
           {           	
               k=(k)%(i+1);            
               if(k==0)return head;      
               for(int j=0;j<i-k;j++)
               {
              	 slow=slow.next;
               }
               break;
           }
           fast=fast.next;
       }
       while (fast.next !=null) {
      	 fast=fast.next;
      	 slow=slow.next;
       }        
       fast.next=head;
       ListNode team=slow.next;
       slow.next=null;
       return team;
  }

在这里插入图片描述

62不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径?
在这里插入图片描述

例如,上图是一个7 x 3 的网格。有多少可能的路径?

示例 1:

输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1 . 向右 -> 向右 -> 向下
2 . 向右 -> 向下 -> 向右
3 . 向下 -> 向右 -> 向右

示例 2:

输入: m = 7, n = 3
输出: 28

提示:

1 <= m, n <= 100
题目数据保证答案小于等于 2 * 10 ^ 9

分析:

可用搜素,但是更是入门级别的动态规划。其状态方程为: 在dp[i][j]=dp[i-1][j]+dp[i][j-1];当然有特殊情况是需要考虑的,就是最上一行和最左一列以及起始位置。因为会出现越界的情况。

  • 你可以特殊判断,先处理边界然后再进行计算。
  • 但是你也可以像我一样,设置的二维数组扩大一点,把边界也当成一个普通情况处理,只不过将dp[0][1]或者dp[1][0]其中设为一个能够正确计算dp[1][1]=1即可(妙啊)。

在这里插入图片描述

实现代码为:

public int uniquePaths(int m, int n) {
    int dp[][]=new int[m+1][n+1];
    dp[0][1]=1;
    for(int i=1;i<m+1;i++)
    {
        for(int j=1;j<n+1;j++)
        {
            dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
    }
    return  dp[m][n];
}

在这里插入图片描述

不同路径Ⅱ

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
在这里插入图片描述

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1

这题你可以使用搜索,其实跟搜索关系越来越大了,但依然可以使用dp,就是在遍历的时候遇到障碍物的位置跳过计算即可 。该位置始终为0即可。

实现代码为:

 public int uniquePathsWithObstacles(int[][] obstacleGrid) {
     int m=obstacleGrid.length;
     int n=obstacleGrid[0].length;
     int dp[][]=new int[m+1][n+1];
     dp[0][1]=1;
     for(int i=1;i<m+1;i++)
     {
         for(int j=1;j<n+1;j++)
         {
             if(obstacleGrid[i-1][j-1]!=1)
             dp[i][j]=dp[i-1][j]+dp[i][j-1];
         }
     }
     //System.out.println(Arrays.deepToString(dp));
     return  dp[m][n];
 }

在这里插入图片描述

最后

本次打卡结束了,明日继续更新,恳请csdn的朋友们帮个忙🙏,微信搜索「bigsai」关注我的原创公众号,新人初期希望大家能够支持一下,白嫖电子书,回复「进群」加入力扣打卡群,欢迎来撩谢谢!
在这里插入图片描述
在这里插入图片描述

Big sai CSDN认证博客专家 数据结构与算法 爬虫 Java
原创公众号:「bigsai」,回复【bigsai】获取珍藏pdf书籍资源,回复【进群】即可加入leetcode打卡群。分享Java,数据结构与算法,python爬虫知识,期待和优秀的你成为朋友!
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值