

为了方便叙述,将【对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和】这一个操作记为 x 操作
当我们读到下面这句话的时候,我们就可以清晰地将这道题分为两种情况

简单证明:
根据上述的题目分析,我们可以知道,当重复执行 x 的时候,数据会陷入到一个 【循环】之中。而【快慢指针】有一个特性,就是在一个圆圈里,快指针总是会追上慢指针的,也就是说他们总会相遇在一个位置上。如果相遇的位置的值是 1 ,那么这个数一定是快乐数;如果相遇的位置不是 1 的话,那么就不是快乐数。
1.把数 n 的每一位的数都提取出来,循环迭代以下步骤
直到 n 的值变为 0;
2.提取每一位的时候,用一个变量 tmp 记录这一位的平方与之前提取位数的平方和
class Solution {
int bitsum(int n)
{
int sum=0;
while(n)
{
int t=n%10;
sum+=t*t;
n/=10;
}
return sum;
}
public:
bool isHappy(int n) {
int slow=n;
int fast=bitsum(n);
while(slow!=fast)
{
slow=bitsum(slow);
fast=bitsum(bitsum(fast));
}
return slow==1;
}
};博主笔记(字迹有点丑,请大家见谅):


题目示例:

设两个指针 left ,right 分别指向容器的左右两个端点,此时容器的容积:
v = (right - left)* min(height[right],height[left])
容器的左边界为 height[left],右边界为 height[right]
为了方便叙述,我们假设 【左边边界】小于 【右边边界】。
如果此时我们固定一个边界,改变另一个边界,水的容积会有如下变化形式:
由此可见,左边界和其余边界的组合情况都可以舍去。所以我们可以 left++ 跳过这个边界,继续去判断下一个右边界。(那在本题里就是先比较左右谁小,如果左边小就left++,右边小就right--)
当我们不断重复上述过程,每次都可以舍去大量不必要的枚举过程,直到 left 与 right 相遇。期间产生的所有的容积里面的最大值,就是最终答案
class Solution {
public:
int maxArea(vector<int>& height) {
int left=0,right=height.size()-1,ret=0;
while(left<right)
{
int v=min(height[left],height[right])*(right-left);
ret=max(ret,v);
if(height[left]<height[right]) left++;
else right--;
}
return ret;
}
};博主笔记(字迹有点丑,请大家见谅):

往期回顾:
【优选算法必刷100题】第001~002题(双指针算法):移动零、复写零问题
总结:本篇博客分享了两个经典算法题的解题思路:快乐数问题采用快慢指针法判断循环类型,盛水容器问题利用对撞指针优化计算。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持