【力扣算法题】双指针-战场上的矛与盾的组合(移动零)&(快乐数)

[复制链接]
发表于 2025-12-21 01:12:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

媒介
🌟🌟本期讲授关于力扣算法两道双指针标题分析~~~
🌈感爱好的小同伴看一看小编主页:GGBondlctrl-CSDN博客
🔥 你的点赞就是小编不绝更新的最大动力                                       
🎆那么废话不多说直接开整吧~~
 

目次
📚️1.移动零
1.1标题要求
1.2标题分析
1.3代码编译
📚️2.快乐数
2.1标题要求
2.2标题分析
1.规定容器举行判断(简单)
2.双指针的算法(困难)
2.3代码编译
📚️3.总结


 

📚️1.移动零

1.1标题要求

移动零的标题位置,在这里:283. 移动零 - 力扣(LeetCode)
本标题如下:
   给定一个数组 nums,编写一个函数将全部 0 移动到数组的末端,同时保持非零元素的相对次序。
  请注意 ,必须在不复制数组的环境下原地对数组举行操纵。
  也就就表达:给一个数组,将全部的0移动到数组的反面,然后前面的数字的顺是稳定的:
   一个数组:[0  ,1  ,0  ,3  ,2]:颠末改变后编酿成了:[1  ,3  ,2  ,0  ,0]
  如下图:
 
1.2标题分析

本标题像这种一样寻常都是利用的双指针的算法,一样寻常就是设置三个区间,左边就是处理处罚过没有0的区间,中心全部都是零,然后右边就是没有处理处罚的数字
注意:这里的指针不是学习c语言中的指针,这里的指针就是用数组的下标举行模拟,这里指针就是下标;

此时我们的思绪就是:
   早先:cur=0,dest=0
  然后:cur今反面移动,如果遇到零就不管,若遇到非0的数,那么就和dest所示的数字举行交换,然后两个加加;
  末了:判断两个cur是否已经到达了末端的位置,这个就是一个循环跳出的条件
  1.3代码编译

如下所示:
  1. class Solution {
  2.     public void moveZeroes(int[] nums) {
  3.         int cur=0,dest=0;
  4.         for(;cur<nums.length;cur++){
  5.             
  6.             if(nums[cur]!=0){
  7.                 int temp=nums[cur];
  8.                 nums[cur]=nums[dest];
  9.                 nums[dest]=temp;
  10.                 dest++;
  11.             }
  12.            
  13.         }
  14.     }
  15. }
复制代码
注意:这里由于每次cur都会加加,以是在循环里就不消操纵cur了,然后期间,还添加了一个交换的操纵,在我们学习语言的初期,就已经相识这个交换的过程,小编就不在举行过多的赘述了;
📚️2.快乐数

一个小打趣就是,这里的快乐数实在挂着简单的标签,实则这里的操纵一点也不简单,还一点也不快乐,看看各人的反应吧:

哈哈哈哈,以是这道题实在一点也不快乐;
2.1标题要求

力扣的标题标泉源:202. 快乐数 - 力扣(LeetCode)
标题如下所示:
   「快乐数」 界说为:
  

  • 对于一个正整数,每一次将该数更换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也大概是 无穷循环 但始终变不到 1。
  • 如果这个过程 效果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false
  总结就是:每次数字举行每一位的平方相加,然后看看是否为一,不是一就继承举行每一位的平法相加的操纵;如下所示:
   19  ----82-----68-----100----1
  此时这个就是一个快乐数字~~~ 
2.2标题分析

1.规定容器举行判断(简单)

这里就是通过一个容器存储每次得到的数字,然后拿到一个数字后,与容器中的数字举行比力,看看是否存在,若存在就返回失败,反之若得到1,那么就返回true;
为啥如果存在就直接返回false呢??
如下图所示:

可以看到,此时若存在一样的值,就表现进入了一个循环的状态,那么此时就不大概拿到1了;
 以是某一刻拿到了1,此时就可以跳出循环了,若存在两个相称的数,就可以直接返回false了,由于反面就不会拿到1了~~~
2.双指针的算法(困难)

此时我们可以利用一个快慢的指针的模拟的操纵,由于这里没有数组的下标的样式,以是这里我们就可以或许用现实的数字举行表现
   快指针:一次移动两步
  慢指针:一次移动一步
  重点: 此时这两个指针肯定是会存在相遇的环境,由于当为1的时间,就会举行全部是1的循环,那么我们就只须要判断,相遇的点是否是1,如果一就表现是快乐数,若相遇的数字不是1,那么此时就表现,进入了如上图所示的循环;
如下图所示:
 

如果一个快乐的数字,那么环境就是如下所示的:

2.3代码编译

第一种算法的环境:
  1. class Solution {
  2.     public boolean isHappy(int n) {
  3.         List<Integer> list = new ArrayList<>(10);
  4.         while (n != 1) {
  5.             n = Sum(n);
  6.             if (list.contains(n)) {
  7.                 return false;
  8.             }
  9.             list.add(n);
  10.         }
  11.         return true;
  12.     }
  13.     public int Sum(int num) {
  14.         int sum = 0;
  15.         while (num > 0) {
  16.             int n = num % 10;
  17.             num /= 10;
  18.             sum += n * n;
  19.         }
  20.         return sum;
  21.     }
  22. }
复制代码
注意:这里就须要界说一个方法举行数字平法相加的算法,这里的循环条件就是是否为一,大概进入循环了,直接跳出;
 第二种算法的代码:
  1. class Solution {
  2.     public boolean isHappy(int n) {
  3.         int slow = n;
  4.         int fast = Sum(n);
  5.         while (slow != fast) {
  6.             slow = Sum(slow);
  7.             fast = Sum(fast);
  8.             fast = Sum(fast);
  9.         }
  10.         if (slow == 1) {
  11.             return true;
  12.         } else {
  13.             return false;
  14.         }
  15.     }
  16.     public int Sum(int num) {
  17.         int sum = 0;
  18.         while (num > 0) {
  19.             int n = num % 10;
  20.             num /= 10;
  21.             sum += n * n;
  22.         }
  23.         return sum;
  24.     }
  25. }
复制代码
注意:我们进入循环的条件是两者不等,以是这里我们这里初始化两个指针的时间不能相称,这里fast要举行两次平方相加的过程,slow只须要举行一次平方相加的过程;
📚️3.总结

 对于双指针,本期重要讲授了一个移动零,与快乐数的操纵,小编发起各人举行接洽,在看了小编的标题分析后可以或许本身编写代码~~
🌅🌅🌅~~~~末了盼望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感爱好的话,就关注小编吧。

                 😊😊  等候你的关注~~~

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表