当前位置: 首页 > news >正文

【力扣】hot100系列(一)哈希部分解析(多解法+时间复杂度分析)

本专栏文章持续更新,新增内容使用蓝色表示。

1. 两数之和 - 力扣(LeetCode)

梦开始的地方,不多言。

49. 字母异位词分组 - 力扣(LeetCode)

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]

输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

【解法一】

根据题目描述,不难想到可以对每一位进行排序,排序之后,字母异位词可以拥有相同的key值。

比如"ate","eat","tea"排序之后都为 aet,所以可以循环对每一位进行处理,排序后相同的字母放在一起,可以使用 map,key 值为字符串,value 值由于要存储多个字符串,所以使用 vector<string>。

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {map<string, vector<string>> ans;// 遍历每一位string key;for (auto& value : strs) {key = value;sort(key.begin(), key.end());        // 排序ans[key].push_back(value);}// 由于返回类型为vector<vector<string>>,所以此处需要处理一下vector<vector<string>> res;for (auto& pair : ans) {res.push_back(pair.second);}return res;}
};

注意:C++里sort 函数返回值类型为 void,sort(key.begin(), key.end());会直接改变key。

时间复杂度为 O(n * L * log L)

n 为输入数组 strs 的长度(字符串的个数), L 为数组中字符串的平均长度。其中 L*Log L 是sort函数的时间复杂度。

以第一个循环为例:

        for (auto& value : strs) {       // O(n)key = value;    # O(L)sort(key.begin(), key.end());    // O(L*Log L)ans[key].push_back(value);        // O(L)}

时间复杂度取最大的,O(n*L) 和 O(n*L*Log L) 中,后者的更大,与第二个循环相比依旧是 O(n * L * log L)更大,所以这个函数整体的时间复杂度为 O(n * L * log L)。

 优化方法:使用 unordered_map<string, vector<string>> ans; 字面意思,这个类型不会自动排序,所以也会更快一点。

空间复杂度 O(n * L),存储所有字符串

【解法二】使用字符计数编码

看到这道题,我的第一想法有考虑过使用所有的字符之和作为key值,显然这并不合适,不过可以使用字符序列作为key值。

原始的key值是"00000000000000000000000000",共26位,代表26个英文字母。从第0位开始,依次代表a,b,c,d......,出现一个字符,对应位加1。

以abc为例,想要增加对应位的值,可以依次遍历abc字符串,对每一位减去字符‘a’,a-a=0, b-a=1, c-a=2,使用这种方法可以找到对应位的下标,然后++即可。

"abc" → "11100000000000000000000000"

"ddd" → "00030000000000000000000000"

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {unordered_map<string, vector<string>> ans;for (auto& value : strs) {string key = string('0', 26);for (auto v : value) {key[v - 'a']++;}ans[key].push_back(value);}vector<vector<string>> res;for (auto& pair : ans) {res.push_back(pair.second);}return res;}
};

这种方法相较于上一解法,没有使用sort函数,所以时间复杂度上有优化。

依旧假设 n 为输入数组 strs 的长度(字符串的个数), L 为数组中字符串的平均长度。

        for (auto& value : strs) {            // O(n)string key = string('0', 26);        // O(1)for (auto v : value) {            // O(L)key[v - 'a']++;            // O(1)}ans[key].push_back(value);        // O(L)}

时间复杂度: O(n * L),空间复杂度: O(n * k) 。

128. 最长连续序列 - 力扣(LeetCode)

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

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

示例1 :

输入:nums = [100,4,200,1,3,2,4,4]
输出:4
 

示例2:

nums=[]

0

解法一

class Solution {
public:int longestConsecutive(vector<int>& nums) {if (nums.size() <= 1) return nums.size();sort(nums.begin(), nums.end());int ans = 1;int current = 1;  // 当前连续序列长度for (int i = 1; i < nums.size(); i++) {// 跳过完全相同的元素if (nums[i] == nums[i - 1]) {continue;}// 连续数字if (nums[i] == nums[i - 1] + 1) {current++;        # 当然也可以选择每一步都更新} else {// 序列中断,更新,重置ans = max(ans, current);current = 1;}}ans = max(ans, current);       # 不要忘记这一步return ans;}
};

时间复杂度:sort函数的时间复杂度为O(n*log n),循环的时间复杂度为O(n),所以最终的为O(n*log n)。

解法二

加了去重。

class Solution {
public:int longestConsecutive(vector<int>& nums) {// 第一个想法排序sort(nums.begin(), nums.end());// 但是要求O(n)级别,双指针?// 发现问题,排序之后是不完全递增// 想办法消除nums.erase(unique(nums.begin(), nums.end()), nums.end());if (nums.size() <= 1)return nums.size();int pre = 0, end = 1;int ans = 1;for (end; end < nums.size();end++) {if (nums[end] - nums[end - 1] != 1) {ans = max(ans, end - pre);pre = end;} }ans = max(ans, end - pre);return ans;}
};

同上时间复杂度为O(n*log n)。


如有问题或建议,欢迎在评论区中留言~

http://www.dtcms.com/a/394199.html

相关文章:

  • 用AI开发HTML双语阅读工具助力英语阅读
  • AI论文速读 | 当大语言模型遇上时间序列:大语言模型能否执行多步时间序列推理与推断
  • 如何使用升腾C92主机搭建本地Linux编译服务器并通过Windows映射访问共享目录
  • 测试DuckDB-rs项目中的示例程序
  • 分布式协议与算法实战-实战篇
  • 【硬件-笔试面试题-105】硬件/电子工程师,笔试面试题(知识点:详细讲讲什么是链表和数组)
  • 【获取地址栏的搜索关键字】功能-总结
  • 关于__sync_bool_compare_and_swap的使用及在多核多线程下使用时的思考
  • 【嵌入式简单外设篇】-433MHz 无线遥控模块
  • 计算机视觉(opencv)实战三十——摄像头实时风格迁移,附多种风格转换
  • 【数据分享】《中国农村统计年鉴》(1985-2024年)全pdf和excel
  • 2025年中国研究生数学建模竞赛“华为杯”C题 围岩裂隙精准识别与三维模型重构完整高质量成品 思路 代码 结果分享!全网首发!
  • [Linux]文件与 fd
  • FFmpeg 深入精讲(二)FFmpeg 初级开发
  • 睡眠脑电技术文章大纲
  • 计算机等级考试Python语言程序设计备考•第二练
  • 【Python】面向对象(一)
  • Jetson 设备监控利器:Jtop 使用方式(安装、性能模式、常用页面)
  • 「数据获取」《商洛统计年鉴》(2001-2024)
  • 链表的探索研究
  • 2025年工程项目管理软件全面测评
  • JAVA算法练习题day17
  • Nacos:服务注册和配置中心
  • Linux 命令行快捷键
  • EasyClick JavaScript Number
  • LeetCode:42.将有序数组转化为二叉搜索树
  • 海外代理IP网站有哪些?高并发场景海外代理IP服务支持平台
  • JavaScript数据交互
  • 11.2.5 自定义聊天室
  • 力扣:字母异味词分组