LeetCode高频算法刷题记录3

news2024/11/19 2:36:23

文章目录

  • 1. 搜索旋转排序数组【中等】
    • 1.1 题目描述
    • 1.2 解题思路
    • 1.3 代码实现
  • 2. 有效的括号【简单】
    • 2.1 题目描述
    • 2.2 解题思路
    • 2.3 代码实现
  • 3. 买卖股票的最佳时机【简单】
    • 3.1 题目描述
    • 3.2 解题思路
    • 3.3 代码实现
  • 4. 环形链表【简单】
    • 4.1 题目描述
    • 4.2 解题思路
    • 4.3 代码实现
  • 5. 岛屿数量【中等】
    • 5.1 题目描述
    • 5.2 解题思路
    • 5.3 代码实现

1. 搜索旋转排序数组【中等】

题目链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/
参考题解:https://leetcode.cn/problems/search-in-rotated-sorted-array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/

1.1 题目描述

整数数组 nums 按升序排列,数组中的值 互不相同

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例2:

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例3:

输入:nums = [1], target = 0
输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -10^4 <= target <= 10^4

1.2 解题思路

要达到题目要求的时间复杂度,肯定得考虑二分法。如果是一般的有序数组,直接二分很容易实现搜索。把数组旋转过后,得到的数组从中间分开,一定会有一半是有序的,满足最左边的元素小于最右边的元素,而另一半无序数组一定不满足这个条件(可以脑补一下)。所以在处理题目给出的数组时,可以在有序的那一半进行搜索,根据目标值是否在这个有序区间来更新左右边界。

1.3 代码实现

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int len = nums.size();
        if(len == 1)
            return nums[0] == target ? 0 : -1;
        int left = 0, right = len - 1;
        while(left <= right) {
            int mid = (left + right) / 2;
            if(nums[mid] == target)
                return mid;
            if(nums[left] <= nums[mid]) {
                if(nums[left] <= target && target < nums[mid])
                    right = mid - 1;
                else
                    left = mid + 1;
            }
            else {
                if(nums[mid] < target && target <= nums[right])
                    left = mid + 1;
                else
                    right = mid - 1;
            }
        }
        return -1;
    }
};

2. 有效的括号【简单】

题目链接:https://leetcode.cn/problems/valid-parentheses/
参考题解:https://leetcode.cn/problems/valid-parentheses/solution/you-xiao-de-gua-hao-by-leetcode-solution/

2.1 题目描述

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例1:

输入:s = “()”
输出:true

示例2:

输入:s = “()[]{}”
输出:true

示例3:

输入:s = “(]”
输出:false

提示:

  • 1 <= s.length <= 10^4
  • s 仅由括号 ‘()[]{}’ 组成

2.2 解题思路

对于括号匹配问题,首先考虑用先进后出的堆来实现。每遇到一个左括号,就把它 push 入堆;每遇到一个右括号,就与堆顶的左括号比对看是否匹配。如果不匹配,或者字符串扫完后堆非空(有多余的左括号),则返回无效,否则返回有效。

2.3 代码实现

class Solution {
public:
    bool isValid(string s) {
        unordered_map<char, char> pairs = {
            {')', '('},
            {'}', '{'},
            {']', '['}
        };
        stack<char> lefts;
        for(int i = 0; i < s.length(); ++i) {
            if(!pairs.count(s[i]))
                lefts.push(s[i]);
            else {
                if(lefts.empty() || pairs[s[i]] != lefts.top())
                    return false;
                lefts.pop();
            }
        }
        if(lefts.empty())
            return true;
        else
            return false;
    }
};

3. 买卖股票的最佳时机【简单】

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
参考题解:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/solution/121-mai-mai-gu-piao-de-zui-jia-shi-ji-by-leetcode-/

3.1 题目描述

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例2:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

提示:

  • 1 <= prices.length <= 10^5
  • 0 <= prices[i] <= 10^4

3.2 解题思路

对于每一天的价格,如果是历史最低价,则把它记录下来,否则就将其与此前历史最低价算利润差,看是不是比截止到这天记录过的最大利润还要高。为什么可以这样做?因为如果这一天不是历史最低价,即便后面的股票价格再高,与这天的利润差也不可能会比与之前的历史最低价利润差更高。注意这里每次参考的历史最低价都是只考虑了这一天及之前出现过的价格,而不是全局的最低价。

3.3 代码实现

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int ans = 0;
        int min_price = prices[0];
        for(int i = 0; i < prices.size(); ++i) {
            if(prices[i] < min_price)
                min_price = prices[i];
            else if(prices[i] - min_price > ans)
                ans = prices[i] - min_price;
        }
        return ans;
    }
};

4. 环形链表【简单】

题目链接:https://leetcode.cn/problems/linked-list-cycle/
参考题解:https://leetcode.cn/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode-solution/

4.1 题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例1:
在这里插入图片描述

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例2:
在这里插入图片描述

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例3:
在这里插入图片描述

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:

  • 链表中节点的数目范围是 [0, 10^4]
  • -10^5 <= Node.val <= 10^5
  • pos 为 -1 或者链表中的一个 有效索引

4.2 解题思路

最简单的方法就是用哈希表,把遍历过的节点都存下来,判断是否有重复访问的节点,但是这样会引入额外的空间开销。另一种方法是使用快慢指针,快指针每次移动两下,慢指针每次只移动一下,如果存在环的话,这两个指针会在某个时刻指向同一个节点。注意fast和slow开始时不能同时指向head,因为循环体中是先判断fast和slow是否重合,再往后移动,一开始都指向head的话循环体内第一个if判断完就直接返回了。此外边界情况要考虑周全。

4.3 代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == nullptr || head->next == nullptr) {
            return false;
        }
        ListNode *fast = head->next;
        ListNode *slow = head;
        while(fast->next != nullptr && fast->next->next != nullptr) {
            if(fast == slow)
                return true;
            fast = fast->next->next;
            slow = slow->next;
        }
        return false;
    }
};

5. 岛屿数量【中等】

题目链接:https://leetcode.cn/problems/number-of-islands/
参考题解:https://leetcode.cn/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/

5.1 题目描述

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例1:

输入:grid = [
[“1”,“1”,“1”,“1”,“0”],
[“1”,“1”,“0”,“1”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“0”,“0”,“0”]
]
输出:1

示例2:

输入:grid = [
[“1”,“1”,“0”,“0”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“1”,“0”,“0”],
[“0”,“0”,“0”,“1”,“1”]
]
输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 ‘0’ 或 ‘1’

5.2 解题思路

扫描整个二维网格,如果某个位置是 1 ,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0 ,这就表明该位置已经是属于当前搜索的岛屿的一部分了。只要是连通的部分,就会在一次深度搜索中被全部置 0 ,也就是形成了一个岛屿。把搜索过的位置标记为 0 是避免以其为起始节点再重复进行搜索。最终的岛屿数量就是进行深度优先搜索的次数。深度优先搜索可以用递归实现,每次往当前位置的上下左右节点进行递归搜索。

5.3 代码实现

class Solution {
public:
    void dfs(vector<vector<char>>& grid, int row, int col) {
        int num_rows = grid.size();
        int num_cols = grid[0].size();
        grid[row][col] = '0';
        if(row - 1 >= 0 && grid[row - 1][col] == '1')
            dfs(grid, row - 1, col);
        if(row + 1 < num_rows && grid[row + 1][col] == '1')
            dfs(grid, row + 1, col);
        if(col - 1 >= 0 && grid[row][col - 1] == '1')
            dfs(grid, row, col - 1);
        if(col + 1 < num_cols && grid[row][col + 1] == '1')
            dfs(grid, row, col + 1);
        return;
    }
    int numIslands(vector<vector<char>>& grid) {
        int ans = 0;
        int num_rows = grid.size();
        int num_cols = grid[0].size();
        if(!num_rows)
            return 0;
        for(int row = 0; row < num_rows; ++row) {
            for(int col = 0; col < num_cols; ++col) {
                if(grid[row][col] == '1') {
                    ++ans;
                    dfs(grid, row, col);
                }
            }
        }
        return ans;
    }
};

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

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

相关文章

ChatGPT Plus 插件最全解读

前言&#xff1a; OpenAI放出大招&#xff0c;向所有ChatGPT Plus用户开放联网功能和众多插件&#xff0c;允许ChatGPT访问互联网并使用70个第三方插件。 本批第三方插件能够全方位覆盖衣食住行、社交、工作以及学习等日常所需&#xff0c;基本上能够扮演24小时私人助理的角色…

SaleSmartly聊天机器人如何帮助您的电商业务

从基于规则的机器人到虚拟助手&#xff0c;聊天机器人正在成为网络交互的标准。越来越多的企业正在使用它们来吸引客户、改善客户服务并增强用户体验。现在有非常多的软件也提供聊天机器人的帮助&#xff0c;比如SaleSmartly&#xff08;ss客服&#xff09;&#xff0c;本文以它…

【包真】我的第一次webpack优化,首屏渲染从9s到1s

目录 前言 1.生产环境关闭productionSourceMap、css sourceMap 2.分析大文件&#xff0c;找出内鬼 3. 逐个包优化 TreeShaking 使用cdn加载第三方js 懒加载有间接依赖的包 moment.js的优化 还有进步空间&#xff1f; 最后 前言 本文基于vue2(虽然vue…

我的小实验项目:实现人体红外采集控制LED灯亮灭

从传感器电路图中找到红外感应&#xff0c;找到接口D2&#xff0c;可以看出&#xff0c;采集的信息从D2进入 从核心板电路图找到D2接口&#xff0c;发现引脚为PB8 并用相似的方法&#xff0c;找到用于代表有人无人的LED灯 在STM32CubeMx里设置 在Keil里设置代码 main.c&#x…

智慧物业如何整合生态资源,小程序技术或成为突破口

数字物业和智慧社区成为了当前数字化转型的热点领域。这些新兴技术的应用&#xff0c;不仅为业主提供了更加便捷、高效的服务&#xff0c;也为物业公司和城市管理带来了全新的运营模式和管理方式。 根据数据显示&#xff0c;截至2021年底&#xff0c;中国物业服务企业智慧化改造…

基于Java+SpringBoot+Vue前后端分离网上银行系统设计与实现(视频讲解)

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Element-ui中el-table展开行

类似这样的需求还记录不记录呢&#xff0c;其实我觉得是没必要的&#xff0c;但是想来还是记录一下吧&#xff0c;因为element-ui里面组件本身也很多&#xff0c;其中el-table的配置样式需求更是很多很多&#xff0c;所以这还是决定来记录一下&#xff0c;以后再有类似的需求也…

linux内核篇-输入输出系统(块设备,字符设备)

计算机系统的输入和输出系统都有哪些呢&#xff1f;有键盘、鼠标、显示器、网卡、硬盘、打印机、CD/DVD 等等&#xff0c;多种多样。但是对于操作系统来讲&#xff0c;却是一件复杂的事情&#xff0c;因为这么多设备&#xff0c;形状、用法、功能都不一样&#xff0c;怎么才能统…

SpringBoot中整合Swagger2接口文档

目录 1、maven依赖 2、swagger2 注解整体说明 2.1、请求类的描述 2.2、方法和方法参数的描述 2.3、方法的响应状态的描述 2.4、对象的描述 3、请求类的描述 3.1、Api&#xff1a;请求类的说明 3.2、示例&#xff1a; 4、方法和方法参数的描述 4.1、ApiOperation&#xff1a…

Linux 中的文件类型

目录 Linux文件类型说明 软链接 软链接特点 软链接工作过程 正常原文件a工作流程 文件a的软链接工作流程 硬链接 硬链接的特点 文件a的硬链接工作流程 软链接与硬链接的比较 测试软链接以及硬链接 1.进入根目录 2.创建test目录 3.进入test目录中&#xff0c;并创建a…

基于Redis的分布式锁,Redisson的简单使用和常用配置

介绍 Redisson是一个在Redis基础上实现的Java驻内存数据网格。Redisson提供了使用Redis的最简单最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离&#xff0c;从而让使用者能够将精力更集中的放在处理业务逻辑上。 Redisson官方文档地址&#xff1a;https://githu…

蛋糕烘焙店小程序开发 让生活多点甜

蛋糕甜品因为较高的颜值、香甜的口感深受大众喜欢&#xff0c;当我们路过一家蛋糕烘焙店的时候&#xff0c;飘香的味道让我们流连忘返。但是互联网时代&#xff0c;各个行业都在转型&#xff0c;蛋糕烘焙店也需要由传统线下店面向线上线下结合的方式转变&#xff0c;以求摆脱区…

数据对象属性分类

数据集由数据对象组成&#xff0c;一个数据对象代表一个实体。数据对象又称样本、实例、数据点或对象。属性&#xff08;attribute&#xff09;是一个数据字段&#xff0c;表示数据对象的一个特征。属性向量&#xff08;或特征向量&#xff09;是用来描述一个给定对象的一组属性…

MySQL之单表访问方法

前言 本文章收录在MySQL性能优化原理实战专栏&#xff0c;点击此处查看更多优质内容。 本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的&#xff1a;从根儿上理解MySQL》 对于我们这些MySQL的使用者来说&#xff0c;MySQL其实就是一个软件&#xff0c;平时用的最多的就是查询功…

快码住!!! 二叉树概念、重要性质、存储结构 技巧大总结!

文章目录 树树的概念树的表示树在实际中的应用 二叉树二叉树的概念特殊的二叉树 二叉树的性质二叉树性质应用的练习题 二叉树的存储结构顺序结构链式结构 树 树的概念 树是一种非线性的数据结构&#xff0c;它是由n(n>0)个有限结点组成的一个具有层次关系的集合。把它叫做…

语言模型及Word2vec与Bert简析

语言模型可以对一段文本的合理性概率进行估计&#xff0c;对信息检索&#xff0c;机器翻译&#xff0c;语音识别等任务有着重要的作用。就以前的学习笔记&#xff0c;本文简单总结了NLP语言模型word2vec和bert分享给大家&#xff0c;疏漏之处&#xff0c;望请指出&#xff0c; …

Go语言的简介和环境搭建

Go语言的简介和环境搭建 带你了解什么是Go语言 如何安装和配置Go的开发环境 静态强类型&#xff0c;编译型语言&#xff01;&#xff01;&#xff01; 1.简介 1.1介绍 Go 也称为 Golang&#xff0c;两个是一个东西。谷歌弄得。创造者都是大佬&#xff0c;所以说这个编程语言很…

PSP - AlphaFold2 Multimer 的 Heteromer (异聚体) MSA 逻辑

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/130733737 同源多聚体 (Homomer) 是由相同的蛋白质亚基组成的,而异源多聚体 (Heteromer) 是由不同的蛋白质亚基组成的。同源多聚体的亚基之间通常有对称的相…

BFT 最前线 | OpenAI开放网络浏览和插件;“360AI商店”上线;Bing市场份额不升反降;亚马逊机器人配送中心投产

原创 | BFT机器人 AI视界 TECHNOLOGY NEWS 01 OpenAI将向所有ChatGPT Plus用户推出网络浏览和插件 OpenAI将向所有ChatGPT Plus用户推出网络浏览和插件近日&#xff0c;OpenAI发文称&#xff0c;将在本周&#xff08;5.15-5.21日&#xff09;内向所有ChatGPT Plus用户推出网络…

【Python scikit-learn】零基础也能轻松掌握的学习路线与参考资料

Python是一种广泛使用的编程语言&#xff0c;随着数据科学领域的不断发展&#xff0c;Python成为了数据科学的主要工具之一。scikit-learn是Python中一款非常流行的机器学习库&#xff0c;它为广大科学家和工程师提供了一种简单而有效的方法来解决机器学习问题。 本文将从以下…