算法学习day23

一、k个一组翻转链表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

 思路:

1.首先得到链表的长度size;然后在size>=k的范围里面进行翻转长度为k的链表。

2.while(size>=k) 在这个循环中,我们需要知道翻转的起点和终点 以及下一次翻转的起点。

pre(起点的前一个) start(起点) end(终点) newStart(新的起点) 并且使用cur节点为每次循环存储新的起点。

3.反转链表的步骤:

   3.1.找到前一个节点pre 

   3.2.找到end,end.next=null(断开链表)

   3.3 然后reverse(start) 翻转之后start变成尾结点 end变成头结点。

   3.4 重新连接 pre.next=end; pre=start; start.next=newStart cur=newStart

 代码:
class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (k == 1) return head;ListNode dummyHead = new ListNode();dummyHead.next = head;ListNode pre = dummyHead;ListNode cur = head;//指向当前节点int size = getSize(cur);while (size >= k) {ListNode start = cur;ListNode end = cur;//end指向k范围内的最后一个for (int i = 1; i < k; i++) {end = end.next;}//下一个头结点=end.nextListNode nextGroupHead = end.next;//断开链条end.next = null;reverseLinkedList(start);pre.next = end;//end变成头结点start.next = nextGroupHead;pre = start;cur = nextGroupHead;size -= k;}return dummyHead.next;}public void reverseLinkedList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr!= null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}}public int getSize(ListNode head) {int size = 0;while (head!= null) {size++;head = head.next;}return size;}
}

二、最长连续序列

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

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

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
思路:

使用哈希表对元素进行处理,先把数组中的元素都加到哈希表中

遍历表中的每一个元素,如果存在contains(num-1),直接continue;

如果num-1不存在,说明这个元素是它最长连续序列的开始,从这里开始计算。

while(set.contains(cur)){cur++;}然后Math.max(res,cur-num+1);

时间复杂度为:O(n)

代码:
class Solution {public int longestConsecutive(int[] nums) {Set<Integer> set=new HashSet<>();for(int num:nums){set.add(num);}int res=0;for(int num:set){//如果集合里面不含有把它小一的元素的话 那么就要从它开始计数int cur=num;if(!set.contains(cur-1)){while(set.contains(cur+1)){cur++;}res=Math.max(res,cur-num+1);}}return res;}
}

筛除素数的方法:

数字包括素数和合数。合数:除了能被1和本身整除外、还能被其他数整除的数。

1.埃氏筛法:

时间复杂度为O(n*loglogn

思想:

1.使用boolean[]数组来对数字进行标记,如果是true表示是非质数,false表示是质数。

2.boolean[0]==boolean[1]=true;(0和1都不是质数)。

3.从2开始遍历,如果遇到boolean[i]==false,表示这个数为质数,那么就要对以该数为因数的合数置true。举个例子:遍历到3的时候,是一个质数。3*3,3*4,3*5,3*6 ...。以它为因数的合数都要置为true。为什么从3*3开始,不从2开始。因为遍历到2这个质数的时候,已经算过了

代码:
    int n = 100000;boolean[] prime = new boolean[n + 1];{// 埃氏筛 时间复杂度为O(n*log(logn))for (int i = 2; i <= n; i++) {if (!prime[i]) {// 如果遇到质数for (int j = i; j <= n / i; j++) {prime[i * j] = true;}}}prime[0] = prime[1] = true;}

三、统计不是特殊数字的数字数量
 

给你两个 正整数 l 和 r。对于任何数字 xx 的所有正因数(除了 x 本身)被称为 x 的 真因数

如果一个数字恰好仅有两个 真因数,则称该数字为 特殊数字。例如:

  • 数字 4 是 特殊数字,因为它的真因数为 1 和 2。
  • 数字 6 不是 特殊数字,因为它的真因数为 1、2 和 3。

返回区间 [l, r] 内 不是 特殊数字 的数字数量。

题意简化:

找l->r中,除了本身之外因数数量2 的数字。哪些数字符合这样的规则:质数的平方数。

那么本题就是要在l->r中找某个数字的平方根是质数。

思路:

首先将l->r中的平方根范围取出来,如果x是平方数,那么sqrt(x)就是边界。如果sqrt(x)不是整数,那么就要向上取整。右边界应该是向下取整。

代码:
class Solution {int n = 100000;boolean[] prime = new boolean[n + 1];{// 埃氏筛 时间复杂度为O(n*log(logn))for (int i = 2; i <= n; i++) {if (!prime[i]) {// 如果遇到质数for (int j = i; j <= n / i; j++) {prime[i * j] = true;}}}prime[0] = prime[1] = true;}public int nonSpecialCount(int l, int r) {if (r == 1)return 1;int total = r - l + 1;int left = (int)Math.ceil(Math.sqrt(l));int right = (int)Math.floor(Math.sqrt(r));System.out.println("left:"+left+"right:"+right);int res = 0;for (int i = left; i <= right; i++) {int square=i*i;if (!prime[i])res++;}return total - res;}
}
补充:如何去判断一个数字是完全平方数

int value=(int)Math.sqrt(i);

return value*value==i;

四、平方数之和(双指针法)

题意:

给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 + b^2 = c 。

思路:

1.使用双指针法,最开始a和b的范围应该是0和sqrt(c);

2从两边不断向里边逼近,当a越接近与b的时候,a^2+b^2是最大的。

3.如果遇到a^2+b^2>c,说明b要往左移动减小总和;如果遇到a^2+b^2<c,说明a要往右移动增加总和;如果相等,直接返回true

代码:
class Solution {public boolean judgeSquareSum(int c) {int a=0;int b=(int)Math.floor(Math.sqrt(c));//取c的根 并且向下取整while(a<=b){if(a*a==c-b*b)return true;else if(a*a>c-b*b)b--;else a++;}return false;}
}

五、快乐数(快慢指针/哈希表)

   快乐数  定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。
  • 1 <= n <= 231 - 1
思路:

1.对于一个n,下一个数最大为810。(因为n最大为十位数,假设每一位置上都为9,也是9*9*10=810)

2.因此下一个数只能从1-810的范围里面出现,如果重复出现了,那么必然走到了循环里。就看重复出现之前有没有出现1。

3.这种思路可以借助于HashSet来实现,也可以通过快慢指针判断是否有环。

HashSet
class Solution {public boolean isHappy(int n) {HashSet<Integer> set=new HashSet<>();while(n!=1&&!set.contains(n)){set.add(n);n=happyNum(n);}return n==1;}public int happyNum(int num){int res=0;while(num>0){res+=Math.pow(num%10,2);num/=10;}return res;}
}
快慢指针:
class Solution {public boolean isHappy(int n) {int slow=n,fast=happyNum(n);while(slow!=fast){slow=happyNum(slow);fast=happyNum(happyNum(fast));}return slow==1;}public int happyNum(int num){int res=0;while(num>0){res+=Math.pow(num%10,2);num/=10;}return res;}
}

六、哈希表一一映射关系 (单词规律/同构字符串)

单词规律:

给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。

pattern = "abba"                    s ="dog dog dog dog"   这样会出现多对一的情况

pattern = "aaaa"                    s ="dog fish  fish dog"   这样会出现一对多的情况

思路:

因此只建立一个map集合是无法正确映射他们的关系的,可能会出现一对多或者多对一的情况。好的办法就是建立两个map集合,实现一一映射的关系。

eg:pattern=abba s=dog dog dog dog;a不在map1中,添加<a,dog>;dog不在map2中,添加<dog,a>;b不在map1中,此时b对应的是dog。但是在map2中,dog只对应了a。因此不符合。 

代码:
class Solution {public boolean wordPattern(String pattern, String s) {if(s.length()==1)return true;String[] spl=s.split(" ");Map<String,Character> sTop=new HashMap<>();Map<Character,String> pTos=new HashMap<>();if(pattern.length()!=spl.length)return false;//如果两个长度不一样直接返回falsefor(int i=0;i<spl.length;i++){char ch=pattern.charAt(i);String str=spl[i];if((pTos.containsKey(ch)&&!(pTos.get(ch).equals(str)))||(sTop.containsKey(str)&&!(sTop.get(str)==ch))){return false;}pTos.put(ch,str);sTop.put(str,ch);}return true;}
}

七、分数到小数
 

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。

如果小数部分为循环小数,则将循环的部分括在括号内。

输入:numerator = 4, denominator = 333
输出:"0.(012)"
思路:

两个数相除结果可能有:整数、有限小数、无限循环小数。

1.先判断是否是正数if(a%b==0)return xxx

2.如果结果不是整数,那么继续判断是有限小数还是无限循环小数

   2.1 有限小数:最终a*=10 a%b==0的 比如说2/5,2*10/5=4  a%b==0;

   2.2 无限循环小数:会存在循环节的,10/6666666666

注意:

1.要判断两个数字的正负号

2.判断循环节的时候,使用哈希表进行判断。如果新计算出的余数在哈希表中出现过,那么就说明从map.get(a)。这个位置到现在是循环节。

3.String.format("%s(%s)",x,x);%s为占位符,表示转换后的格式为x(x);

代码:
/**
如何处理:先把整数处理出来,如果有余数可能是有限小数或者无限循环小数
1.先拼接整数
2.如果可以除尽 就说明是有限小数
3.不能除尽 找寻环节*/
class Solution {public String fractionToDecimal(int numerator, int denominator) {long a=(long)numerator;long b=(long)denominator;if(a%b==0)return String.valueOf(a/b);StringBuilder sb=new StringBuilder();if(a<0^b<0)sb.append('-');a=Math.abs(a);b=Math.abs(b);//取整数sb.append(a/b).append(".");//取小数a%=b;//使用map集合 记录每一次余数的位置 用来判断是否存在循环节Map<Long,Integer> map=new HashMap<>();while(a!=0){int index=sb.length();map.put(a,index);a*=10;sb.append(a/b);a%=b;//如果map集合中遇到了重复的余数 说明后面的数字一定是循环的if(map.containsKey(a)){int c=map.get(a);return String.format("%s(%s)",sb.substring(0,c),sb.substring(c,sb.length()));}}return sb.toString();}
}

八、两个列表的最小索引总和

假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。

你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。

思路:

使用哈希表,如果另一个人喜爱的餐厅里面也包含遍历的该餐厅,那么就计算下标和。这里计算最小下标和的时候有一个小技巧:如果sum<min,清空集合:list.clear(),list.add(num),min=sum;这样保证了在集合中的元素是下标和最小的餐厅

代码:
class Solution {public String[] findRestaurant(String[] list1, String[] list2) {Map<String,Integer> map=new HashMap<>();for(int i=0;i<list2.length;i++){map.put(list2[i],i);}//将每一个餐厅的下标和都放进map中List<String> res=new ArrayList<>();int min=Integer.MAX_VALUE;for(int i=0;i<list1.length;i++){if(map.containsKey(list1[i])){int index=i+map.get(list1[i]);if(index<min){res.clear();res.add(list1[i]);min=index;}else if(index==min){res.add(list1[i]);}}}return res.toArray(new String[res.size()]);}
}

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

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

相关文章

【C++BFS算法】886. 可能的二分法

本文涉及的点 CBFS算法 LeetCod886. 可能的二分法 给定一组 n 人&#xff08;编号为 1, 2, …, n&#xff09;&#xff0c; 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人&#xff0c;那么他们不应该属于同一组。 给定整数 n 和数组 dislikes &#xff0c;其…

电脑桌面记事本便签哪个好,有哪些好用的桌面备忘记事工具推荐

在寻找高效办公的道路上&#xff0c;我们经常需要记住许多重要的事情&#xff0c;然而人的记忆力终究有限&#xff0c;这时候就需要依赖一些工具来帮助我们进行提醒。一款好的电脑桌面记事本便签、桌面日程安排软件就像是一位得力助手&#xff0c;它不仅能够帮助我们合理规划时…

项目经理的开源工具指南:优化您的选择过程

国内外主流的10款开源项目管理系统对比&#xff1a;PingCode、Worktile、禅道、Teambition、Gogs、码云 Gitee、Jira、Redmine、ProjectLibre、OpenProject。 在选择合适的开源项目管理系统时&#xff0c;很多团队面临诸多挑战&#xff1a;功能是否全面&#xff1f;易用性如何&…

Excel模拟计算演示-以矩阵乘计算密度为例

Excel模拟计算演示-以矩阵乘计算密度为例 1.参考链接2.CUDA_Occupancy_Calculator截图3.矩阵乘计算密度模拟计算的操作步骤及效果 安装好CUDA之后,/usr/local/cuda-12.1/tools/CUDA_Occupancy_Calculator.xls里会看到"TABLE(,B17)"这样的表达式,原来是模拟计算的结果…

3V升5V输出800mA可驱动10MA驱动蜂鸣片芯片AH6910

135-3806-7573今天&#xff0c;我们将深入解析一款名为AH6910的芯片&#xff0c;这款芯片以其独特的3V至5V宽电压输入范围、800mA的高输出电流能力&#xff0c;以及能够轻松驱动低至10mA需求的蜂鸣片&#xff0c;成为了众多电子项目中的优选元件。######一、AH6910芯片概述 AH…

RIP路由协议

RIP-路由信息协议V1/V2/NG NG版为ipv6专用 距离矢量型IGP路由协议&#xff0c;使用跳数作为度量&#xff0c;支持等开销负载均衡&#xff1b;基于UDP&#xff0c;520端工作&#xff0c;基于UDP V1和V2的区别&#xff1a; 1、v1为有类别协议--不支持VLSM/CIDR&#xff0c;即使使…

ic进阶|性能篇02:一文带你了解一种特殊的并行技术-展开!

本期文章让我们聊聊一种数字ic设计技术——展开&#xff0c;展开用于产生一个一次迭代就相当于原有结构的多次迭代的新电路结构。其相当于之前聊过的折叠技术的反向操作&#xff0c;折叠使用一个功能单元通过多次迭代来完成原有电路结构一次迭代的操作&#xff0c;相对于通过时…

中电金信:云原生时代IT基础设施管理利器——基础设施即代码(IaC)

在数字化转型、零售业务快速发展、信创建设驱动下&#xff0c;应用架构、技术架构、基础架构都已向云原生快速演进&#xff0c;银行业IT基础设施管理产生了非常大的变化&#xff0c;当前银行业&#xff0c;正在开展新一轮的核心应用系统重构、基础平台统一建设等重点任务&#…

Playwright 的使用

Playwright 的特点 支持当前所有主流浏览器&#xff0c;包括 Chrome 和 Edge &#xff08;基于 Chromiuns&#xff09;, Firefox , Safari 支持移动端页面测试&#xff0c;使用设备模拟技术&#xff0c;可以让我们在移动Web 浏览器中测试响应式的 Web 应用程序 支持所有浏览…

x264编解码库 -介绍和使用示例

目录 1&#xff1a;X264简单介绍 1.1&#xff1a;编译x264 1.2&#xff1a;x264简单介绍 1.3&#xff1a;x264的优势 1.4&#xff1a;x264与FFmpeg的关系 1.5&#xff1a;x264 编解码原理 1.6 进一步学习资源 2&#xff1a;demo效果 3&#xff1a;完整代码 4&#xff1a;附件…

6 网络

6 网络 1、概念2 IP地址3、套接字4、TCP协议4.1 TCP协议的基本特征4.2 建立连接4.4 终止连接4.5 编程模型 5、UDP协议5.1 UDP协议的基本特性5.2 常用函数5.3 UDP通信模型 6、域名解析 1、概念 计算机网络是实现资源共享和信息传递的计算机系统 ISO/OSI网络协议模型 TCP/IP协…

C语言进阶 10. 字符串

C语言进阶 10. 字符串 文章目录 C语言进阶 10. 字符串10.1. 字符串10.2. 字符串变量10.3. 字符串输入输出10.4. 字符串数组10.5. 单字符输入输出10.6. 字符串函数strlen()10.7. 字符串函数strc()10.8. 字符串函数strcpy()10.9. 字符串搜索函数10.10. PAT10-0. 说反话 (20)10-1.…

idea中导入外部依赖并打包到jar包中

前言&#xff1a; 很多时候在我们写项目对接三方的时候都需要导入三方jar包&#xff0c;而这时候我们用平常的pom里面写依赖发现导入不了&#xff08;直接把jar包放在本地导入的话打包的话也不会将该依赖打包进我们项目的jar包&#xff09;&#xff0c;我在网上找了几种方法 …

Linux网络-ss命令

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注我&#xff0c;我尽量把自己会的都分享给大家&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux服务器作为一个常用的网络服务器&#xff0c;主要的作用就是向客户端提供网络…

【C++】C++11中R字符串的作用

在 C11 中添加了定义原始字符串的字面量 1.定义和基本使用 定义方式为&#xff1a; R"xxx(原始字符串)xxx"其中 () 两边的字符串可以省略&#xff0c;R只会处理括号中的字符串。 原始字面量 R 可以直接表示字符串的实际含义&#xff0c;而不需要额外对字符串做转义…

谷歌团队新技术Alchemist:使用扩散模型对材料属性进行参数控制

Alchemist是由谷歌团队和麻省理工学院联合研发的一项创新技术&#xff0c;它利用扩散模型对材料属性进行精细的参数控制。这项技术的核心在于能够对真实图像中的物体材料属性进行调整&#xff0c;包括粗糙度、金属感、反照率和透明度等。Alchemist的实现依赖于先进的文本到图像…

【时时三省】(C语言基础)循环语句while(2)

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 getchar和scanf的作用 示例: int main ( ) &#xff5b; char password[20] ( 0 ) ; printf ( "请输入密码&#xff1a;> " )&#xff1b; scanf ( " &#xff05;s…

Sping项目只能勾选17和21 (已解决) 导致的后续Invalid bound statement (not found):

问题发现 今天创建项目的时候发现 idea初始化spring的时候选择不了Java8 解决方案:替换URL为 https://start.aliyun.com/ 将IDEA页面创建Spring项目&#xff0c;其实是访问spring initializr去创建项目。故我们可以通过阿里云国服去间接创建Spring项目。 将https://start.spr…

使用 VMware vCenter Server(vSphere Client)迁移 ESXi 虚拟机

我需要将虚拟机 k8s-dev-node4从 ESXi 主机 192.168.1.161 迁移到 ESXi 主机 192.168.1.162 上&#xff0c;使用 VMware vCenter Server&#xff08;vSphere Client&#xff09;在浏览器上可视化操作&#xff0c;将这个需求变的非常简单。 1、选中需要迁移的虚拟机&#xff0c…

【AI落地应用实战】Amazon Bedrock +Amazon Step Functions实现链式提示(Prompt Chaining)

一、链式提示 Prompt Chaining架构 Prompt Chaining 是一种在生成式人工智能&#xff08;如大型语言模型&#xff09;中广泛使用的技术&#xff0c;它允许用户通过一系列精心设计的提示&#xff08;Prompts&#xff09;来引导模型生成更加精确、丰富且符合特定需求的内容。 P…