LeetCode热题 100

news2025/1/15 16:28:10

两数之和

暴力枚举

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for(int i=0; i<nums.size()-1; i++){
            for(int j=i+1; j<nums.size(); j++){
                if(target == nums[i] + nums[j]){
                    return {i,j};
                }
            }
        }
        return {};
    }
};

哈希表
方法一的时间复杂度较高的原因是寻找target-x的时间复杂度过高。
因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找到它的索引。

使用哈希表,可以将寻找target-x的时间复杂度从O(N)降到O(1)。

class Solution{
public:
	vector<int> twoSum(vector<int>& nums, int target){
		unordered_map<int, int> hashtable;
		for(int i=0; i<nums.size(); i++){
			auto it = hashtable.find(target-nums[i]);
			if(it != hashtable.end()){
				return {it->second,i};
			}
			hashtable[nums[i]] = i;
		}
		return {];
	}
};

字母异位词分组

给一个字符串数组,请你将字母异位词组合在一起。

排序
由于互为字母异位词的两个字符串包含的字母相同。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> strMap;
        for(string& str:strs){
        	string key = str;
        	sort(key.begin(),key.end());
        	mp[key].emplace_back(str);
        }
        
        vector<vector<string>> ans;
        for(auto it=mp.begin(); it!=mp.end();it++){
        	ans.empalce_back(it->second);
        }
        return ans;
    }
};

最长连续序列

给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请设计并实现时间复杂度为O(n)的算法解决此问题。

哈希表
我们考虑枚举数组中的每个数x,考虑以其为起点,不断尝试匹配x+1,x+2,…是否存在,假设最长匹配到了x+y,那么以x为起点的最长连续序列即为x,x+1,…,x+y,其长度为y+1,我们不断枚举并更新答案即可。

对于匹配的过程,暴力的方法是O(n)遍历数组去看是否存在这个数,但其实更高效的方法是使用一个哈希表存储数组中的数,这样查看一个数是否存在即能优化至O(1)的时间复杂度。

仅仅是这样,我们的算法时间复杂度最坏情况下还是会达到O(n²)(外存需要枚举O(n)个数,内存需要暴力匹配O(n)次),无法满足题目的要求。

仔细分析这个过程,会发现其中执行了很多不必要的枚举,如果已知有一个从x开始的连续序列,而我们却从x+1开始,那么得到的结果肯定不会优于枚举x为起点的答案,因此我们在外层循环的时候碰到这种情况跳过即可。

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> hashTable;
        for(const int&num:nums){
        	hashTable.insert(num);
        }
		
		int maxLength = 0;
		for(const int&num:hashTable){
			if(!hashTable.count(num-1)){
				int currentNum = num;
				int currentLen = 1;
				
				while(hashTable.count(currentNum+1)){
					currentNum++;
					currentLen++;
				}
				maxLength = max(maxLength, currentLen);
			}
		}
		return maxLength;
    }
};

移动零

给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。

双指针
使用双指针,左指针指向当前已处理好的序列的尾部,右指针指向待处理序列的头部。

右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。

无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
    	int n = s.size();
    	if(n <= 1){
    		return n;
    	}

		int l = 0;
		int r = 1;
		unordered_set<char> charMap;
		charMap.insert(s[l]);
		int maxLen = 1;

		while(r < n){
			if(charMap.count(s[r])){
				maxLen = max(maxLen, r-l);
				charMap.remove(s[l]);
				l++;
			}else{
				charMap.insert(s[r]);
				r++;
			}
		}
		maxLen = max(maxLen,r-l);
		return maxLen;
    }
};

和为k的子数组

枚举

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int count = 0;
        for(int i=0; i<nums.size(); i++){
            int sum = 0;
            for(int j=i; j>=0; j--){
                sum += nums[j];
                if(sum == k){
                    count++;
                }
            }
        }
        return count;
    }
};

前缀和+哈希表优化
方法一的瓶颈在于对每个i,我们需要枚举所有的j来判断是否符合条件。

定义pre[i]为0,…,i的和

pre[i] = pre[i-1] + nums[i]

[j,…i]子数组和为k:

pre[i] - pre[j-1] == k

pre[j-1] = pre[i] - k;

最大子数组和

找出一个具有最大和的连续子数组,返回最大和(至少包含一个元素)。

动态规划
用f(i)代表以第i个数结尾的连续子数组的最大和。
可以考虑nums[i]单独成为一段还是加入f(i-1)对应的一段。
f(i) = max{nums[i],f(i-1)+nums[i]}

不难给出一个时间复杂度、空间复杂度均为O(n)的实现,即用一个f数组来保存f(i)的值,用一个循环求出所有f(i)。
f(i)只和f(i-1)有关,所以可以用一个变量维护即可,类似于滚动数组。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n = nums.size();
        if(n == 1){
            return nums[0];
        }
        int sum = nums[0];
        int maxSum = sum;
        for(int i=1; i<n; i++){
            if(sum < 0){
                sum = nums[i];
            }else{
                sum += nums[i];
            }
            maxSum = max(maxSum,sum);
        }
        return maxSum;
    }
};

合并区间

合并所有重叠的区间,并返回一个不重叠的区间。
排序
如果按照区间的左端点排序,那么在排完序的列表中,可以合并的区间一定是连续的。
在这里插入图片描述
用数组merged存储最终的答案。
首先,将列表中的区间按照左端点升序排序。
然后我们将第一个区间加入merged数组中,并按顺序考虑之后的每个区间:

  • 如果当前区间的左端点在数组merged中最后一个区间的右端点之后,那么它们不会重合,直接将区间加入数组merged的末尾。
  • 否则,重合,需要将当前区间的右端点更新数组merged中最后一个区间的右端点,将其重置为两者的较大值。
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> merged;
        
        sort(intervals.begin(), intervals.end());

        for(int i=0; i<intervals.size(); i++){
            int L = intervals[i][0], R = intervals[i][1];
            if(!merged.size() || merged.back()[1] < L){
                merged.push_back({L,R});
            }else{
                merged.back()[1] = max(merged.back()[1], R);
            }
        }
        return merged;
    }
};

轮转数组

class Solution {
public:
    void reverseNum(vector<int>& nums,int start,int end){
        while(start < end){
            swap(nums[start++],nums[end--]);
        }
    }
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        k = k%n;

        reverseNum(nums,0,n-1);
        reverseNum(nums,0,k-1);
        reverseNum(nums,k,n-1);
    }
};

使用额外的数组
可以使用额外的数组来将每个元素放在正确的位置。

除自身以外数组的乘积

answer[i]等于nums中除nums[i]之外其余各元素的乘积。

左右乘积列表
利用索引左侧所有数字的乘积和右侧所有数字的乘积(即前缀与后缀)相乘得到答案。

  1. 初始化两个空数组L和R。对于给定索引i,L[i]代表的是i左侧所有数字的乘积,R[i]代表的是右侧所有数字的乘积。
  2. 我们需要用两个循环来填充L和R数组的值。对于数组L,L[0]应该是1。L[i] = L[i-1]*nums[i];
  3. R[Length-1] = 1。R[i] = R[i+1]*nums[i]。
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> L(n,1);
        vector<int> R(n,1);
        vector<int> res(n);

        for(int i=1; i<n; i++){
            L[i] = L[i-1]*nums[i-1];
        }
        for(int i=n-2; i>=0; i--){
            R[i] = R[i+1]*nums[i+1];
        }
        for(int i=0;i<n;i++){
            res[i] = L[i]*R[i];
        }
        return res;
    }
};

空间复杂度O(1)的方法
仅管上面的方法已经能够很好地解决这个问题,但是空间复杂度并不为常数。

由于输出数组不算在空间复杂度内,那么我们可以将L或R数组用输出数组来计算。
先把输出数组当做L数组来计算,然后再动态构造R数组得到结果。

  1. 初始化answer数组,对于给定索引i,answer[i]代表的是i左侧所有数字的乘积。
  2. 没有构造R数组。用一个遍历来跟踪右边元素的乘积。并更新数组answer[i] = answer[i] * R,R=R*nums[i]
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n,1);
        for(int i=1; i<n; i++){
            res[i] *= res[i-1]*nums[i-1];
        }
        int R = 1;
        for(int i=n-1; i>=0; i--){
            res[i] = res[i]*R;
            R *= nums[i];
        }
        return res;
    }
};

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

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

相关文章

FlashSequence: SORA视频生成长序列任务训练解决方案

作者&#xff1a;黄奕桐、沈雯婷、艾宝乐、王昂、九丰 摘要 我们提出了长序列训练方案 FlashSequence 并集成在 PAI-TorchAcc &#xff08;阿里云机器学习平台开发的Pytorch上的大模型训练加速框架&#xff09;中&#xff0c;该方案能够支持SORA类超长序列模型的高效训练。在…

解密Prompt系列31. LLM Agent之从经验中不断学习的智能体

前言 Agent智能体的工作流可以简单分成两种&#xff1a;一种是固定的静态工作流&#xff0c;一种是智能体自主决策的动态工作流。 静态流程的Agent举几个例子&#xff0c;例如新闻热点追踪推送Agent&#xff0c;每日新论文摘要总结Agent&#xff0c;它们的优点是可控&#xf…

SpringSecurity6从入门到实战之初始用户如何存储到内存(依旧源码级别讲解,耐心看完会有收获)

SpringSecurity6从入门到实战之初始用户如何存储到内存 文接上回,根据登录表单的提交最终得知用户相关信息存储在内存中.那么SpringSecurity是如何在项目启动时将用户信息存储到内存中的呢? 这里我们还是先回到SpringBoot加载配置的地方 UserDetailServiceAutoConfigutation 类…

【PowerDesigner】创建和管理CDM之使用实体间关系

目录 &#x1f30a;1. PowerDesigner简介 &#x1f30d;1.1 常用模型文件 &#x1f30d;1.2 PowerDesigner使用环境 &#x1f30a;2. 创建和管理CDM &#x1f30d;​​​​​​2.1 新建CDM &#x1f30d;2.2 使用实体间关系 &#x1f30c;a. 使用联系 &#x1f30c;b. …

2024年智能医疗与生物医药国际会议(ICIHB 2024)

2024 International Conference on Intelligent Healthcare and Biopharmaceuticals 【1】大会信息 会议简称&#xff1a;ICIHB 2024 大会地点&#xff1a;中国珠海 会议官网&#xff1a;www.icihb.com 投稿邮箱&#xff1a;icihbsub-paper.com 【2】会议简介 2024年智能医…

CISA网络安全事件应急手册

《Cybersecurity Incident & Vulnerability Response Playbooks》是美国CISA&#xff08;Cybersecurity and Infrastructure Security Agency&#xff0c;网络安全和基础设施安全局&#xff09;于2021年11月份发布的指导手册&#xff0c;是基于FCEB&#xff08;Federal Civ…

硬核新品!M4E EDU民航考培一体无人机

天途上新啦&#xff01; 应我国民用无人机首项强制性国家标准《民用无人驾驶航空器系统安全要求》&#xff0c;天途对现有小型无人机训练机的飞控、电池、感知避障和电子围栏等软硬件全面升级设计&#xff0c;严格按国标GB42590-2023规范生产。 M4E EDU四轴多旋翼无人机是天途…

浅谈word格式:.doc和.docx的优缺点及区别

.doc和.docx是两种最为常见的文档格式&#xff0c;它们在多个方面存在着显著的区别。首先&#xff0c;从版本角度来看&#xff0c;.doc是Microsoft Office Word 2003及之前版本的保存类型&#xff0c;而.docx则是Word 2007及之后版本的保存类型。这一区别直接影响了文档在不同版…

【递归、搜索与回溯】穷举vs暴搜vs深搜vs回溯vs剪枝

穷举vs暴搜vs深搜vs回溯vs剪枝 1.全排列2.子集 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 管他什么深搜、回溯还是剪枝&#xff0c;画出决…

深圳市萨科微半导体有限公司

深圳市萨科微半导体有限公司凭借碳化硅、氮化镓等新材料、功率器件设计加工环节的先进工艺、高效管理和快速扩大生产规模&#xff0c;不断降低产品价格、提高市场的占有率&#xff0c;受到了世界各地客户的认可。萨科微具有高性能高可靠集成电路的独立研发能力和多年技术储备&a…

Craig Federighi 和 John Giannandrea 在 WWDC 上谈论苹果智能技术

WWDC 主题演讲结束后&#xff0c;苹果公司的克雷格-费德里吉&#xff08;Craig Federighi&#xff09;和约翰-吉安南德雷亚&#xff08;John Giannandrea&#xff09;坐下来&#xff0c;更深入地讨论了苹果智能公司在人工智能方面所做的努力&#xff0c;包括该公司是如何训练模…

在AWS上运行的EKS Elastic Kubernetes Service 创建集群Cluster,Node group, Nodes

1. 前提条件 AWS Account: https://aws.amazon.com/free/Installing KubeCtl CLI https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.htmlEKS Cluster RoleIAM Role for Node GroupVPCEC2 Key Pair which can be used to SSH to the worker nodesAWS …

深入理解Vue3.js响应式系统基础逻辑

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

cad导入su线条不在一个平面怎么办?

解决CAD导入sketchup线条不是共面问题&#xff0c;需要考虑到各个步骤如下&#xff1a; 1&#xff09;检查CAD文件。首先要检查CAD文件&#xff0c;确保线条是连接在一起的&#xff0c;并且看看有没有多余的线&#xff0c;以及是否有子线段没有合并&#xff0c;如果有会导致导入…

AdroitFisherman模块测试日志(2024/6/10)

测试内容 测试AdroitFisherman分发包中SHAUtil模块。 测试用具 Django5.0.3框架&#xff0c;AdroitFisherman0.0.31 项目结构 路由设置 总路由 from django.contrib import admin from django.urls import path,include from Base64Util import urls urlpatterns [path(ad…

猫狗识别(超详细版)(py代码)

猫狗识别&#xff08;一&#xff09; 一、图像识别 1.导入必要的库: import torchimport numpy as npimport torchvisionfrom os import pathfrom torchvision import datasets, modelsimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import DataL…

【NUCLEO-G071RB】009——HAL库-显示编译时间

NUCLEO-G071RB&#xff1a;009——HAL库-显示编译时间 编译时间设计目标程序修改运行测试 编译时间 这里的编译时间指的是烧录文件的编译时间&#xff0c;它由编译环境的日期和时间共同决定。 设计目标 1、获取编译时间&#xff0c;默认是ASC码格式 2、将编译时间转换为HEX …

哈尔滨等保如何做?

哈尔滨等保测评是确保信息系统安全稳定运行的重要一环&#xff0c;它涉及到对业务、资产、安全技术和安全管理的全面调研和评估。本文将详细阐述哈尔滨等保测评的实施步骤和注意事项&#xff0c;帮助读者更好地理解和执行等保测评工作。 首先&#xff0c;我们需要明确等保测评的…

新品发布 | 捷云等保一体机2.0全新上市,助力中小企业破解等保难题

等保2.0时代&#xff0c;随着网络威胁不断复杂化和组织化&#xff0c;作为网络安全“弱势群体”的中小企业&#xff0c;等保建设工作正面临着安全意识、管理、人才、资金捉襟见肘等问题&#xff0c;主要体现在以下两个方面&#xff1a; 等保建设流程复杂 中小企事业单位缺乏专…

条件概率的理解

P(A)表示A的先验概率 P(B)表示B的先验概率 P(A | B)表示在B发生的情况下&#xff0c;A的条件概率 P(B | A)表示在A发生的情况下&#xff0c;B的条件概率 先验概率是在进行实验之前基于当前知识对结果概率的最佳合理评估。后验概率是在考虑了新信息后&#xff0c;事件发生的修正…