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

算法日记 - Day5

轮转数组

publicvoidrotate(int[]nums,intk){intn=nums.length;k=k%n;if(k==0)return;reverse(nums,0,n-k-1);reverse(nums,n-k,n-1);reverse(nums,0,n-1);}privatevoidreverse(int[]nums,intfrom,intto){while(from<to){inttemp=nums[from];nums[from++]=nums[to];nums[to--]=temp;}}

除了自身以外数组的乘积


如果用除法,就所有元素乘积,最后遍历每个元素一除,时间复杂度O ( n ) O(n)O(n),空间复杂度O ( 1 ) O(1)O(1)

如果使用暴力,就是从前到后遍历,一个一个乘起来,跳过自己,时间复杂度是O ( n ) O(n)O(n),然后一共n nn个元素,所以是O ( n 2 ) O(n^2)O(n2)时间复杂度,复杂度提高在哪里呢?是因为每次算的时候实际是有重复的,每个位置的nums[i]都被计算使用了( n − 1 ) (n - 1)(n1)次,能不能变为一次呢?

怎么减少重复呢?前缀和!不过不是计算和,而是计算乘积。但是它不是计算前缀和,还要跳过一个数,还不能除法。前缀和 + 后缀和不就可以了

publicint[]productExceptSelf(int[]nums){// 前缀和 + 后缀和int[]answer=newint[nums.length];Arrays.fill(answer,1);intpre=1;// 先计算每个位置处 [0, i - 1] 的前缀乘积for(inti=0;i<nums.length-1;++i){pre*=nums[i];answer[i+1]*=pre;}intback=1;// 再加上每个位置处 [i + 1, nums.length - 1] 的后缀乘积for(intj=nums.length-1;j>0;--j){back*=nums[j];answer[j-1]*=back;}returnanswer;}

矩阵置零

classSolution{publicvoidsetZeroes(int[][]matrix){intn=matrix.length,m=matrix[0].length;boolean[]rowZero=newboolean[n];// 行是否需要置零boolean[]colZero=newboolean[m];// 列是否需要置零for(inti=0;i<n;++i)for(intj=0;j<m;++j)if(matrix[i][j]==0)rowZero[i]=colZero[j]=true;for(inti=0;i<n;++i)if(rowZero[i])for(intj=0;j<m;++j)matrix[i][j]=0;for(intj=0;j<m;++j)if(colZero[j])for(inti=0;i<n;++i)matrix[i][j]=0;}}

时间复杂度是O ( m n ) O(mn)O(mn),这个是没办法优化的,空间复杂度是O ( m + n ) O(m + n)O(m+n),还能优化吗?能,有一种用常量空间的解决方案

哎,为什么能这样呢?你想第一行的如果某个元素它本身是0,你是不是这一列一定是要被清空的,或者这一列它本身是有0的,那最后一定也会被置零的,我放到第一行该列的位置,记录为0没问题吧

但是还有个小问题,需要区分第一行的0是本身这个位置就是0,还是后来置为0的,因为我们是用的第一行第一列来存的,所以后续根据这个置为0的时候,是先把matrix[1][1]右下的位置都根据规则置为空后,再单独处理第一行第一列,假如原来第一行的0是他本身就是0,那我们后续这一行都要清空的,否则就不用操作了 。所以还需要两个标志位。

classSolution{publicvoidsetZeroes(int[][]matrix){intn=matrix.length,m=matrix[0].length;booleanrowZero=false,colZero=false;for(inti=0;i<n;i++)if(matrix[i][0]==0)colZero=true;for(intj=0;j<m;j++)if(matrix[0][j]==0)rowZero=true;// 记录第一行第一列最后是否需要清空for(inti=1;i<n;++i)for(intj=1;j<m;++j)if(matrix[i][j]==0)matrix[i][0]=matrix[0][j]=0;// 遍历for(inti=1;i<n;++i)if(matrix[i][0]==0)for(intj=1;j<m;++j)matrix[i][j]=0;for(intj=1;j<m;++j)if(matrix[0][j]==0)for(inti=1;i<n;++i)matrix[i][j]=0;// 根据第一行第一列清空 matrix[1][1] 右下部分矩阵if(rowZero)for(intj=0;j<m;++j)matrix[0][j]=0;if(colZero)for(inti=0;i<n;++i)matrix[i][0]=0;// 处理第一行第一列}}

相交链表



如果相交,那从后往前,肯定是找到交点的,并且这一部分是他们都有的,但是链表从前往后我们怎么找呢?观察示例 1,A AAB BB链表如果有交点,只可能从他们尾部长度相等的时候开始,也就是A AA第一个结点为4 44的位置,B BB第一个结点为6 66的位置,如果他们A.next == B.next,才会出现交点。所以我们可以先找链表长度,让他们都从尾部往前开始对齐,再往后找交点

/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */publicclassSolution{publicListNodegetIntersectionNode(ListNodeheadA,ListNodeheadB){intlenA=0,lenB=0;ListNodeA=headA,B=headB;// 计算A、B链表长度while(A!=null){lenA++;A=A.next;}while(B!=null){lenB++;B=B.next;}A=headA;B=headB;// 长度对齐if(lenA<lenB){while(lenA!=lenB){B=B.next;lenB--;}}else{while(lenA!=lenB){A=A.next;lenA--;}}// 此时 A 往后的链表长度等于 B 往后的链表长度while(A!=B){A=A.next;B=B.next;}returnA;}}

下面再看一种更好的解法


假设有交点,从交点到结束长度为z zzA AA头节点到交点长度为x xxB BB头节点到交点长度为y yy,有等式x + y + z = = x + y + z x + y + z == x + y + zx+y+z==x+y+z,含义是什么呢?我让p ppheadA \text{headA}headA开始走,它遍历完A AA之后从B BB开始,让q qqheadB \text{headB}headB开始走,它遍历完B BB之后从A AA开始,如果有交点,他们一定会相遇!!!如果没有交点,最后两个人都会为null

classSolution{publicListNodegetIntersectionNode(ListNodeheadA,ListNodeheadB){ListNodep=headA;ListNodeq=headB;while(p!=q){p=p!=null?p.next:headB;q=q!=null?q.next:headA;}returnp;}}
http://www.jsqmd.com/news/1319094/

相关文章:

  • PotPlayer字幕翻译插件完整配置指南:3步实现外语视频无障碍观看
  • 网页转PDF完美解决方案:从浏览器原理到Puppeteer自动化实战
  • ncmdump终极指南:三步解锁网易云NCM音乐,重获数字音乐自由
  • 2026长远自动化保温杯专用设备口碑推荐强势出炉,零套路不踩坑,实力测评看这篇就够 - mypinpai
  • 想找邯郸装配式抗震支架厂家?这些要点助你选到合适的! - 滚动商讯
  • Vue.js奶茶店管理系统开发实战与优化
  • 每日开源 img2threejs:一张参考图,一段可运行的 Three.js 代码AI 驱动 3D 建模的新范式 —— 不给你网格文件,直接给你代码
  • 想找三段式止水螺杆源头厂家?这些途径能帮你! - 滚动商讯
  • SpringBoot校园运动会管理系统开发实践
  • COMSOL模拟注浆工程中浆液粘度的关键影响
  • 2026开封家庭维修口碑排名|全城家电水电维修、全屋便民维保靠谱服务商推荐 - 滚动商讯
  • Linux DNS 查询完全指南:从 dig 入门到精通
  • 才赋源人力资源外包靠谱商家实测排名,价格透明,避坑指南速收藏 - mypinpai
  • Java后端实现Markdown与HTML双向转换:Flexmark-java实战指南
  • Slurm-web:现代化HPC集群Web管理界面的架构设计与技术实现
  • 武汉醇基燃料供应链选择:解读锐醇港储的全链条实践 - 趣闻早乐评
  • 轻量化Hermes-Agent架构设计与技术选型解析
  • 蝴蝶效应:从混沌理论到现实启示
  • Codex、Claude Code、Grok 接入:成本计算与 6 项排错清单
  • 告别模组管理烦恼:XXMI启动器一站式游戏模组管理解决方案
  • PotPlayer字幕翻译插件深度解析:如何用百度翻译API实现无缝观影体验
  • 技术架构图的设计与管理实践指南
  • 2026 安徽工商业光伏落地效率提升:本土服务商属地化能力深度解析 - 滚动商讯
  • DsPdfJS-在 React应用中生成PDF、SVG和PNG文件
  • Hadoop之MapReduce
  • Cheat Engine逆向分析:从内存扫描到代码注入的实战指南
  • 2026国产企业IM市场分析与选型指南
  • 电磁波、光与无线电波:从物理本质到工程应用的全解析
  • 2026儿童摄影十大热门工作室真实横评,选定再拍不交智商税 - mypinpai
  • 深入解读FIO性能测试报告:从IOPS、带宽、延迟到实战诊断