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

算法日记 - Day1

算法日记 - Day1

两数之和

比较经典的题目 两数之和

分析题目,找出数组中a+b = target的两个值,有且只有一个答案 ,并且可以按照任意顺序。

  • 可以按照任意顺序,但是返回的是下标,也就是说我们排序数组,还需要记录他们的初始下标位置
  • 有且只有一个答案,我们找到第一个答案就可以收手了

按照暴力可以解答,但是复杂度是O(n^2),原因是因为我们是遍历的时候,我们已经知道a,因为数组无序,我们不知道每个位置有什么,所以我们还是从头到尾又重新遍历,找有没有target - a这个值。

所以我们其实有两种优化做法,第一种,哈希,我们用哈希来记录有没有这个值。也就是把第二次遍历省下了,时间复杂度是O(n)。如下

publicint[]twoSum(int[]nums,inttarget){Map<Integer,Integer>map=newHashMap<>();for(inti=0;i<nums.length;i++){if(map.containsKey(target-nums[i])){returnnewint[]{i,map.get(target-nums[i])};}else{map.put(nums[i],i);}}returnnull;}

还有一种做法,平均时间复杂度是O(nlogn),时间复杂度主要浪费在了排序上,不如哈希。并且还需要记录原始下标,也就是借助排序后的规律,我们先取i = 0, j = nums.length - 1,如果nums[i] + nums[j] > target,那么说明答案中的[i, j]j需要变小,如果nums[i] + nums[j] < target,那么说明答案中的[i, j]i需要变大。
当我们算完之后再把原始的数组下标返回即可。

publicint[]twoSum(int[]nums,inttarget){int[][]arr=newint[nums.length][2];// 保存值和原始下标for(inti=0;i<nums.length;i++){arr[i][0]=nums[i];arr[i][1]=i;}// 按值排序Arrays.sort(arr,Comparator.comparingInt(a->a[0]));intleft=0;intright=nums.length-1;while(left<right){intsum=arr[left][0]+arr[right][0];if(sum==target){returnnewint[]{arr[left][1],arr[right][1]};}elseif(sum<target){left++;}else{right--;}}returnnull;}

字母异位词分组

字母异位词分组

这个题思路就是你要判断多个字符串数组是不是字母异位词,那就得把每个字符串数组排成某个顺序,看看有哪些字符串数组排好后也符合这个顺序,他们就组成字母异位词。因为都是小写字母,所以正好可以把字符串转为数组再进行排序,然后利用哈希表存储同类结果即可。

publicList<List<String>>groupAnagrams(String[]strs){Map<String,List<String>>hashMap=newHashMap<>();for(Stringstr:strs){char[]charArray=str.toCharArray();Arrays.sort(charArray);Stringkey=newString(charArray);if(!hashMap.containsKey(key)){List<String>value=newArrayList<>();value.add(str);hashMap.put(key,value);}else{hashMap.get(key).add(str);}}returnnewArrayList<>(hashMap.values());}

最长连续序列

最长连续序列

  • 题目说了没排序,但是又说要用O(n)时间复杂度解答,那说明我们不能排序了
  • 连续最长序列,如果我们想知道数字5所在最长序列,那我们就得知道有没有小于它的 2,3,4,有没有大于它的 6,7,8。所以我们可以做哈希,知道哪些数存不存在了。就容易找最长连续序列了。

有个小点可以优化,比如一个最长序列是4 5 6 7 8,你判断 5 最长序列的时候,你判断它有 4, 有 6,7,8,最长连续序列的长度是 5,你判断 6 最长序列的时候,又判断它有 4,5,有 7,8,最长连续序列的长度是 5,是不是有点重复,毕竟是同一个最长序列,你这样搞。我们可以怎么做呢?固定一端,比如如果发现某个值(4)没有紧挨着小于它的,我就去找挨着大于它的,那这样4因为没有3,所以以它为中心找5,6,7,8。但是5,6,7,8不行,直接跳过。或者同样,固定右端,如果发现某个值(8)没有紧挨着大于它的,就跳过。

本质上:利用序列唯一入口,避免重复遍历。

publicintlongestConsecutive(int[]nums){Set<Integer>numsSet=newHashSet<>();for(intnum:nums){numsSet.add(num);}if(nums.length==0)return0;intlongest=1;for(intnum:numsSet){intcurrentLength=1;if(numsSet.contains(num-1)){continue;}intcurr=num;while(numsSet.contains(++curr))currentLength++;longest=Math.max(currentLength,longest);}returnlongest;}
http://www.jsqmd.com/news/1292723/

相关文章:

  • Python全栈项目--智能办公自动化系统
  • 票评选活动制作攻略!详细步骤全解析|注册_页面设置_防刷配置
  • 造了一个 Chat BI:让业务人员用自然语言“对话”Excel 数据
  • 2026年降AI工具测评:免费试用+退款承诺+平台适配横向对比
  • C++项目目录结构设计:从扁平到模块化的工程实践指南
  • 基于Qt5与C++的串口调试助手开发:从原理到工程实践
  • 终极开源硬件控制工具:5步掌握华硕笔记本性能优化神器
  • 2026年长沙自建房门页贴牌供应商优选指南:如何甄选靠谱供应商? - geo交流
  • EEG频带功率计算全流程:从Welch方法到Python实战避坑指南
  • 2026年宁波正规知名的托盘提升机直销厂家哪家权威?这份优选清单为您严选 - geo交流
  • vLLM部署实战:基于PagedAttention解决大模型KV缓存内存瓶颈
  • Python虚拟环境管理全攻略:从原理到实战,掌握多环境查看技巧
  • 穿透式管理落地指南:国企如何借数字化实现“业人融合“战略升级
  • RK3568 Android 11 DDR降频实战:提升工控设备稳定性的原理与操作
  • Veeam配置备份加密策略与灾难恢复实践指南
  • 2026年SCMP采购方向、计划方向、物流方向怎么选——众智商学院张明老师三方向岗位匹配和备考建议 - 众智商学院cppm官方
  • 【考研】2026/7/29
  • 知网普刊投稿全流程与计算机类论文发表技巧
  • 太原烘焙培训市场分析与高性价比机构推荐
  • STM32内部FLASH读写与芯片ID读取:原理、风险与工程实践
  • RT-Thread Studio工程文件结构全解析:从内核源码到应用开发
  • 2026年如何甄选湖北优质公园景观膜结构服务商? - geo交流
  • SOLIDWORKS 2027 新功能前瞻:Beta 测试亮点与重磅功能深度解析
  • AI辅助渗透测试(中):如何使用AI辅助渗透测试
  • 电气工程保研浙大攻略:从专业基础到面试实战的全面指南
  • STM32调试连接丢失:从硬件排查到软件修复的完整指南
  • 从零搭建AI专利语义检索系统,手把手复现BERT+IPC融合模型(含开源代码与训练数据集)
  • 从AT指令到稳定通信:蓝牙串口透传模块实战开发指南
  • ananconda环境默认路径保存在c盘
  • 微电网两阶段鲁棒优化:Matlab实现与工程实践