【LeetCode算法系列题解】第61~65题

news2024/11/26 16:40:52

CONTENTS

    • LeetCode 61. 旋转链表(中等)
    • LeetCode 62. 不同路径(中等)
    • LeetCode 63. 不同路径 II(中等)
    • LeetCode 64. 最小路径和(中等)
    • LeetCode 65. 有效数字(困难)

LeetCode 61. 旋转链表(中等)

【题目描述】

给你一个链表的头节点 head,旋转链表,将链表每个节点向右移动 k 个位置。

【示例1】

在这里插入图片描述

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]

【示例2】

在这里插入图片描述

输入:head = [0,1,2], k = 4
输出:[2,0,1]

【提示】

链表中节点的数目在范围 [0, 500]
− 100 ≤ N o d e . v a l ≤ 100 -100\le Node.val\le 100 100Node.val100
0 ≤ k ≤ 2 ∗ 1 0 9 0\le k\le 2 * 10^9 0k2109

【分析】


在这里插入图片描述

首先由于 k k k 可能很大,当 k k k 超过链表结点数 n n n 时,就变成了重复的循环位移,因此 k k k 需要先对 n n n 取模。

以样例1为例,示意图如上图所示,算法流程如下:

  • 先遍历一遍链表,求出链表长度 n n n,并记下最后一个结点 tail
  • 我们需要将链表的最后 k k k 个结点移动到首部,因此需要先找到倒数第 k + 1 k+1 k+1 个结点 P,也就是正数第 n − k n-k nk 个结点,那么就需要从头结点向后遍历 n − k − 1 n-k-1 nk1 次;
  • tail->next = head
  • head = P->next
  • P->next = nullptr

【代码】

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (!head) return head;  // 需要特判链表为空的情况
        ListNode* tail;
        int n = 0;
        for (auto p = head; p; p = p->next) n++, tail = p;
        k %= n;
        auto p = head;
        for (int i = 0; i < n - k - 1; i++) p = p->next;
        tail->next = head, head = p->next, p->next = nullptr;
        return head;
    }
};

LeetCode 62. 不同路径(中等)

【题目描述】

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start”)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
问总共有多少条不同的路径?

在这里插入图片描述

【示例1】

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

【示例2】

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

【示例3】

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

【示例4】

输入:m = 3, n = 3
输出:6

【提示】

1 ≤ m , n ≤ 100 1\le m, n\le 100 1m,n100
题目数据保证答案小于等于 2 ∗ 1 0 9 2 * 10^9 2109

【分析】


本题是动态规划的数字三角形模型中的裸题,我们定义 f[i][j] 表示从起点走到点 (i, j) 的路径方案数,那么状态的转移有以下几种情况:

  • 如果在第一行,那么只能从左边的点转移过来,即 f[i][j] = f[i][j - 1]
  • 如果在第一列,那么只能从上边的点转移过来,即 f[i][j] = f[i - 1][j]
  • 否则既能从左边转移过来也可以从上边转移过来,即 f[i][j] = f[i][j - 1] + f[i - 1][j]

【代码】

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> f(m, vector<int>(n));
        f[0][0] = 1;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
            {
                if (i) f[i][j] += f[i - 1][j];
                if (j) f[i][j] += f[i][j - 1];
            }
        return f[m - 1][n - 1];
    }
};

LeetCode 63. 不同路径 II(中等)

【题目描述】

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start”)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 10 来表示。

在这里插入图片描述

【示例1】

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

【示例2】

输入:obstacleGrid = [[0,1],[0,0]]
输出:1

【提示】

m = = o b s t a c l e G r i d . l e n g t h m == obstacleGrid.length m==obstacleGrid.length
n = = o b s t a c l e G r i d [ i ] . l e n g t h n == obstacleGrid[i].length n==obstacleGrid[i].length
1 ≤ m , n ≤ 100 1\le m, n\le 100 1m,n100
obstacleGrid[i][j]01

【分析】


和上一题一样,如果 (i, j) 是障碍物,则 f[i][j] = 0,即没有办法走到这个点。如果起点或者终点是障碍物,那么直接返回 0 0 0 即可。


【代码】

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int n = obstacleGrid.size(), m = obstacleGrid[0].size();
        if (obstacleGrid[0][0] || obstacleGrid[n - 1][m - 1]) return 0;  // 特判起点或终点就是障碍物的情况
        vector<vector<int>> f(n, vector<int>(m));
        f[0][0] = 1;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (!obstacleGrid[i][j])  // 如果是障碍物f[i][j]就为0,直接跳过不计算
                {
                    if (i) f[i][j] += f[i - 1][j];
                    if (j) f[i][j] += f[i][j - 1];
                }
        return f[n - 1][m - 1];
    }
};

LeetCode 64. 最小路径和(中等)

【题目描述】

给定一个包含非负整数的 m x n 网格 grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。

【示例1】

在这里插入图片描述

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

【示例2】

输入:grid = [[1,2,3],[4,5,6]]
输出:12

【提示】

m = = g r i d . l e n g t h m == grid.length m==grid.length
n = = g r i d [ i ] . l e n g t h n == grid[i].length n==grid[i].length
1 ≤ m , n ≤ 200 1\le m, n\le 200 1m,n200
0 ≤ g r i d [ i ] [ j ] ≤ 200 0\le grid[i][j]\le 200 0grid[i][j]200

【分析】


这题同样也是数字三角形模型,令 f[i][j] 表示从起点走到 (i, j) 的路径和的最小值,状态转移有如下几种情况:

  • 从上边转移过来,那么结果为从起点走到 (i - 1, j) 的路径和的最小值(f[i - 1][j])加上当前点的值,即 f[i][j] = f[i - 1][j] + grid[i][j]
  • 从左边转移过来同理,转移方程为:f[i][j] = f[i][j - 1] + grid[i][j]

根据 f[i][j] 的定义,我们要求的是最小值,因此最终的状态转移方程为:f[i][j] = min(f[i - 1][j], f[i][j - 1]) + grid[i][j]


【代码】

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> f(n, vector<int>(m, INT_MAX));  // 初始化为正无穷之后便于和自身取min
        f[0][0] = grid[0][0];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
            {
                if (i) f[i][j] = min(f[i][j], f[i - 1][j] + grid[i][j]);
                if (j) f[i][j] = min(f[i][j], f[i][j - 1] + grid[i][j]);
            }
        return f[n - 1][m - 1];
    }
};

LeetCode 65. 有效数字(困难)

【题目描述】

有效数字(按顺序)可以分成以下几个部分:

  1. 一个小数或者整数
  2. (可选)一个 'e''E',后面跟着一个整数

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+''-'
  2. 下述格式之一:
    • 至少一位数字,后面跟着一个点 '.'
    • 至少一位数字,后面跟着一个点 '.',后面再跟着至少一位数字
    • 一个点 '.',后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+''-'
  2. 至少一位数字

部分有效数字列举如下:["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
部分无效数字列举如下:["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]

给你一个字符串 s,如果 s 是一个有效数字,请返回 true

【示例1】

输入:s = "0"
输出:true

【示例2】

输入:s = "e"
输出:false

【示例3】

输入:s = "."
输出:false

【提示】

1 ≤ s . l e n g t h ≤ 20 1\le s.length\le 20 1s.length20
s 仅含英文字母(大写和小写),数字(0-9),加号 '+',减号 '-',或者点 '.'

【分析】


本题需要考虑的情况有很多种,我们一个个分析:

  • e/E 的前后如果为空(在第一个或最后一个位置上),返回 false
  • xx. 或者 .xx 都是合法的,但是 .e/E 是不合法的;
  • e/E 的后面如果有 .,返回 false
  • +/- 只可能在首部或者 e/E 的后面出现一次,其余地方出现均不合法;
  • 如果 . 或者 e/E 出现次数大于1次则不合法;
  • e/E 的后面如果是 +/-,还需要判断下一位有没有内容,如果已经到字符串末尾,也是不合法;
  • 其余情况只要不是 0~9 即为不合法。

【代码】

class Solution {
public:
    bool isNumber(string s) {
        bool has_dot = false, has_e = false;
        if (s[0] == '+' || s[0] == '-') s = s.substr(1);
        if (s.empty()) return false;  // 字符串只有+/-
        if (s[0] == '.' && (s.size() == 1 || s[1] == 'e' || s[1] == 'E')) return false;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == '.')
            {
                if (has_dot || has_e) return false;
                has_dot = true;
            }
            else if (s[i] == 'e' || s[i] == 'E')
            {
                if (has_e || !i || i == s.size() - 1) return false;  // 不止一次出现E或者出现在第一个或最后一个位置
                if (s[i + 1] == '+' || s[i + 1] == '-')  // E后面是正负号还需要继续判断
                {
                    if (i + 1 == s.size() - 1) return false;
                    i++;  // 跳过正负号
                }
                has_e = true;
            }
            else if (s[i] < '0' || s[i] > '9') return false;
        }
        return true;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/980022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线程中的join()、wait() 和 notify()详解及练习题

一、join() Thread 类提供了 join() 方法&#xff0c;用于等待当前线程所调用的其他线程执行完毕。 1、当一个线程调用另一个线程的 join() 方法时&#xff0c;它会被阻塞&#xff0c;直到被调用的线程执行完毕或达到指定的超时时间。 比如&#xff1a;当主线程main中调用了…

手把手教会如何掌握Swagger

文章目录 前言一、Swagger重要组件及作用二、SpringBoot集成Swagger1.环境准备2.配置Swagger3.配置Swagger扫描接口4.配置API分组5.拓展&#xff1a;其他皮肤 三、常用注解1.接口注解2.方法及参数注解3.实体类注解效果如图&#xff1a; ![在这里插入图片描述](https://img-blog…

面向未来的编程方式,做为开发者,很必要了解一下什么是iVX

面向未来的编程方式&#xff0c;做为开发者&#xff0c;很必要了解一下什么是iVX 一前言二什么是传统低代码平台以及传统平台的局限性和作用1.什么是传统低代码平台2.传统平台的局限性 三为什么程序员和技术管理者不太可能接受“低代码”平台&#xff1f;1.低代码的特征2.为什么…

【C++基础】4. 变量

文章目录 【 1. 变量的定义 】【 2. 变量的声明 】示例 【 3. 左值和右值 】 变量&#xff1a;相当于是程序可操作的数据存储区的名称。在 C 中&#xff0c;有多种变量类型可用于存储不同种类的数据。C 中每个变量都有指定的类型&#xff0c;类型决定了变量存储的大小和布局&am…

Windows server 2012安装IIS的方法

Windows Server 2012是微软公司研发的服务器操作系统&#xff0c;于2012年9月4日发布。 Windows Server 2012可以用于搭建功能强大的网站、应用程序服务器与高度虚拟化的云应用环境&#xff0c;无论是大、中或小型的企业网络&#xff0c;都可以使用Windows Server 2012的管理功…

*** error 65: access violation at 0xFFFFFFF4 : no ‘write‘ permission怎么办

我发现是我的单片机型号设置错了&#xff0c;把debug里面的STM32F103ZET6修改为STM32F103ZE就可以正常运行了

信息检索度量指标(MAP@N, P@N)

我们今天遇到的大多数软件产品都集成了某种形式的搜索功能。我们在谷歌上搜索内容&#xff0c;在YouTube上搜索视频&#xff0c;在亚马逊上搜索产品&#xff0c;在Slack上搜索信息&#xff0c;在Gmail上搜索邮件&#xff0c;在Facebook上搜索人等等。 作为用户&#xff0c;工作…

基于SSM+Vue的网上花店系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【问题总结】 记 一次dockerFile构建报错

写在前面&#xff0c; 其实是一个比较摸不着脑袋的bug&#xff0c;记录一下解决的过程&#xff0c;作为备忘录 问题留档 1、场景描述 在尝试使用dockefile构建一个tomcat镜像&#xff0c;内容如下&#xff0c;构建正常通过&#xff0c;但是容器启动失败 FROM centos:7 MAINT…

【办公类-18-02】(Python)教师获奖证书批量打印(教师信息、获奖类型,公章)

背景需求&#xff1a; 同事提出给word批量“添加电子公章&#xff08;png图片&#xff09;的需求 解压文件后&#xff0c;发现&#xff1a; 1、每份WORD文件名是一位老师的证书&#xff0c;需要打开每一份word&#xff0c;插入一个空白电子公章png。 2、每个word文件名包含教…

Redis缓存的高并发问题

Redis 做缓存虽减轻了 DBMS 的压力&#xff0c;减小了 RT&#xff0c;但在高并发情况下也是可能会出现各 种问题的。 1 缓存穿透 当用户访问的数据既不在缓存也不在数据库中时&#xff0c;就会导致每个用户查询都会“穿透” 缓存“直抵”数据库。这种情况就称为缓存穿透。一个…

SSL证书系列--又拍云Let’s Encrypt免费DV SSL证书使用教程

原文网址&#xff1a;SSL证书系列--又拍云Let’s Encrypt免费DV SSL证书使用教程_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何使用又拍云部署Let’s Encrypt免费DV SSL证书。 一、了解Let’s Encrypt 了解和关注SSL证书的朋友&#xff0c;似乎没有理由不知道 Let’s Encr…

java八股文面试[数据库]——数据库锁的种类

数据库锁的种类 MySQL数据库由于其自身架构的特点,存在多种数据存储引擎, MySQL中不同的存储引擎支持不同的锁机制。 MyISAM和MEMORY存储引擎采用的表级锁&#xff0c; InnoDB存储引擎既支持行级锁&#xff0c;也支持表级锁&#xff0c;默认情况下采用行级锁。 BDB采用的是页…

开店星小程序上架教程和后台Request failed with status code 500[undefined]问题处理

开店星小程序上架教程和后台Request failed with status code 500[undefined]问题处理 刚刚安装好开店星网站后台之后都会出现这个code 500[undefined]的错误&#xff0c;需要改一下代码。改好了之后就可以正常使用了。如果大家不懂得这样处理的可以私聊我&#xff0c;帮忙处理…

kettle通过java步骤获取汉字首拼

kettle通过java步骤获取汉字首拼 用途描述 一组数据&#xff0c;需要获取汉字首拼后&#xff0c;输出&#xff1b; 实现效果 添加jar包 pinyin4j-2.5.0.jar 自定义常量数据 Java代码 完整代码&#xff1a; import net.sourceforge.pinyin4j.PinyinHelper; import net.sou…

高潮迭起:探寻Twitch上精彩纷呈的电子竞技赛事直播

Twitch是电子竞技赛事的热门直播平台之一,它为全球范围内的电子竞技比赛提供了广泛的覆盖和直播服务。以下是一些在Twitch上直播的电子竞技比赛和赛事的例子: League of Legends (英雄联盟) Twitch广泛直播英雄联盟的各个赛事,包括全球性的锦标赛如英雄联盟全球总决赛(World …

SLAM从入门到精通(基本框架)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 SLAM是机器人的一个分支。广义上来说&#xff0c;机器人还包括了计算机视觉、语音识别、自然语言处理、机械臂控制、运动控制、机器人导航、机器人…

软件架构师 设计和编码

软件架构师 设计和编码 目录概述需求&#xff1a; 设计思路实现思路分析1.设在设计软件架构时&#xff0c;您需要考虑以下方面&#xff1a;2.在编码方面&#xff0c;您需要具有以下技能&#xff1a; 参考资料和推荐阅读 Survive by day and develop by night. talk for import …

如何绘制英语思维导图?偷偷告诉你这个绘制方法

如何绘制英语思维导图&#xff1f;绘制英语思维导图可以帮助我们更好地理清思路&#xff0c;提高学习和工作效率。同时&#xff0c;英语思维导图还可以帮助我们提高英语表达能力和阅读理解能力&#xff0c;让我们更好地掌握英语学习和应用。因此&#xff0c;绘制英语思维导图是…

msvcr120.dll放在哪里?怎么修复msvcr120.dll文件

当您在运行某些应用程序或游戏时遇到“msvcr120.dll缺失”错误时&#xff0c;这可能会影响您的使用体验。msvcr120.dll是Microsoft Visual C Redistributable的一部分&#xff0c;并且它提供了程序运行所需的运行时支持&#xff0c;今天我们来讨论一下msvcr120.dl文件缺失了要怎…