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

LeetCode算法日记 - Day 2: 快乐数、盛水最多容器

目录

1. 快乐数

1.1 题目分析

1.2 解法

1.3 代码实现

2. 盛水最多的容器

2.1 题目分析

2.2 解法

2.3 代码实现


1. 快乐数

202. 快乐数 - 力扣(LeetCode)

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

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

如果 n 是 快乐数 就返回 true;不是,则返回 false 。

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 231 - 1

1.1 题目分析

  • 操作定义:对于一个正整数 n ,x操作计算其各位数字的平方和。例如,n = 19:
    • 第一次操作:1^2 + 9^2 = 1 + 81 = 82
    • 第二次操作:8^2 + 2^2 = 64 + 4 = 68,依此类推。
  • 循环特性:重复 x 操作时,数据必然进入循环(死循环)。原因如下:
    • 设 x 操作后最大可能值为 9^2 \times 10 = 810 (因为10位数的最大值 9999999999 的平方和不超过810)。
    • 变化范围被限制在 [1, 810] 区间内。
    • 根据鸽巢原理(元素数量超过容器大小时必有重复),经过大于811次操作后,必然出现重复值,形成循环。
  • 循环类型
    • 情况一:循环固定于 1 (即 1 \to 1 \to 1 ),此时该数为快乐数。
    • 情况二:循环在其他值间发生(如 4 \to 16 \to 37 \to 58 \to 89 \to 145 \to 42 \to 20 \to 4 \cdots),但不涉及 1。
    • 两种情况互斥,因此只需检测循环是否在 1 处发生。

1.2 解法

我们可以使用快慢指针来解决,快慢指针是一种高效检测循环的方法。其原理在于:在循环序列中,快指针总会追上慢指针。

算法步骤:

a)初始化指针

  • 慢指针 slow :起始于输入数 n 。
  • 快指针 fast :起始于 x 操作一次后的值(即 bitSum(int n))

b)移动指针

  • 慢指针每次执行一次x操作:slow = bitSum(slow)
  • 快指针每次执行两次x操作:fast = bitSum(bitSum(fast))
  • 重复此过程,直到 slow 与 fast 相遇。

c)判断结果

  • 如果相遇时 slow = 1(或 fast = 1),则是快乐数。
  • 否则,不是快乐数。

d)关键函数

x操作的核心是提取一个数$n$的各位数字并计算平方和。方法如下:

  • 初始化临时变量 int sum  = 0,int t = 0;
  • 循环操作:
    • 提取个位数字:t = n %10
    • 累加平方:sum += t*t 
    • 更新 n:n = n / 10(整数除法)
  • 当 n = 0 时停止,返回 sum。

1.3 代码实现

以下是 Java 的代码实现

class Solution {public int bitSum(int n){int sum = 0;while(n>0){int t = n%10;sum += t*t;n = n/10;}return sum;}public boolean isHappy(int n) {int slow = n;int fast = n;while(true){slow = bitSum(slow);fast = bitSum(bitSum(fast));if(slow == fast){break;}}if(slow == 1){return true;}else{return false;}}
}

2. 盛水最多的容器

11. 盛最多水的容器 - 力扣(LeetCode)

给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 ( i , 0 ) 和 ( i ,height[i] ) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。i n

说明:你不能倾斜容器。

2.1 题目分析

在解决容器最大容积问题时,给定一个数组 height ,其中 height[i] 表示位置$i$处柱子的高度,目标是找到两个柱子,使它们与 x 轴形成的容器能容纳最多的水。容器的容积由宽度(索引差)和高度(较小柱子高度)决定。对撞指针算法通过双指针高效枚举可能解,避免不必要的计算。

2.2 解法

  1. 初始化指针

    • left指针指向数组起始位置(索引0),right指针指向数组末尾位置(索引len(height)-1)。
    • 初始化最大容积max_area = 0
  2. 指针移动逻辑

    • 计算当前容积:int v = Math.min(height[left],height[right])*(right-left);
    • 更新体积为当前最大值。设体积 ret = Math.max(ret,v);
    • 关键决策:比较 height[left] 和 height[right] :
      • 若 height[left]<height[right] ,则移动左指针 left++。
        • 原因:较小高度限制了容积。移动较小边界(左边界)可能遇到更高柱子,从而增大容积;而移动右边界只会减小宽度,受限于当前最矮的柱子,只能体积减小。
      • 否则 height[left]>height[right]  ,移动右指针 right-- 。
        • 原因:类似逻辑,移动较小边界(右边界)可能增大容积。
    • 重复以上过程,直到 left >= right。
  3. 终止条件

    • 当 left  和 right 相遇时,所有有效组合已枚举完毕,返回 ret。

2.3 代码实现

class Solution {public int maxArea(int[] height) {int left = 0, right = height.length-1,ret = 0;while(left<right){int v = Math.min(height[left],height[right])*(right-left);ret = Math.max(ret,v);if(height[left]<height[right]) left++;else right--;}return ret;}
}

http://www.xdnf.cn/news/17040.html

相关文章:

  • 计算机常用英语词汇大全
  • 【unitrix】1.1 readme.md
  • Erdős–Rényi (ER) 模型
  • Android10 系统休眠调试相关
  • 文件编译、调试及库制作
  • 视频水印技术中的变换域嵌入方法对比分析
  • 从 “看懂图” 到 “读懂视频”:多模态技术如何用文本反哺视觉?
  • FPGA实现Aurora 8B10B视频点对点传输,基于GTP高速收发器,提供4套工程源码和技术支持
  • RC和RR的区别
  • 关于npx react-native run-android下载进程缓慢以及进程卡壳等问题的解决方案。
  • iouring系统调用及示例
  • 16核32G硬件服务器租用需要多少钱
  • 【安卓][Mac/Windows】永久理论免费 无限ip代理池 - 适合临时快速作战
  • 【数字图像处理系列笔记】Ch01:绪论
  • Vue2项目—基于路由守卫实现钉钉小程序动态更新标题
  • 20250805
  • GitCode新手使用教程
  • 初学docker
  • 基于k8s环境下的pulsar常用命令(上)
  • 【Lua】题目小练8
  • nflsoi 8.2 题解
  • Druid与JdbcTemplate基本使用
  • vscode 关闭自动更新
  • 从达梦到 StarRocks:国产数据库实时入仓实践
  • Memcached 缓存详解及常见问题解决方案
  • P1002 [NOIP 2002 普及组] 过河卒
  • 06 基于sklearn的机械学习-欠拟合、过拟合、正则化、逻辑回归、k-means算法
  • 【RH124知识点问答题】第8章 监控和管理 Linux 进程
  • 关于解决WinRiver项目动态XmlElement的序列化与反序列化的问题
  • 2.1 vue组件