您的位置:首页 > 文旅 > 旅游 > 免费3d建模软件_国家市场监督局官网_优化排名推广教程网站_北大青鸟培训机构官网

免费3d建模软件_国家市场监督局官网_优化排名推广教程网站_北大青鸟培训机构官网

2025/5/1 4:52:07 来源:https://blog.csdn.net/m0_57082284/article/details/147448432  浏览:    关键词:免费3d建模软件_国家市场监督局官网_优化排名推广教程网站_北大青鸟培训机构官网
免费3d建模软件_国家市场监督局官网_优化排名推广教程网站_北大青鸟培训机构官网

目录

(一)快乐数的C++实现

题意理解

写法一(哈希表)

写法二(栈与列表)

(二)复杂度分析

时间复杂度

空间复杂度

(三)总结


【题目链接】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

(一)快乐数的C++实现

题意理解

        题目是为了判断一种数叫做快乐数,如果对这个数不停地求每一位平方的和,如果最终结果为1,则是快乐数。

写法一(哈希表)

解题思路:

根据题意,我们可以知道关键有以下几个:

(1)获取数的每一位并求平方的和。我们可以通过数学方式解决,假设有一个数为n,则n%10为最后一位的值,n/10为将最后一位去掉。通过不断进行这两步,我们就可以得到n这个数的每一位上的数字,设置一个变量sum将平方的和叠加起来。

(2)和的循环过程。循环条件则为快乐数的判断标准,是否为1,如果是1就返回true;如果不是1就一直进行循环。最大的问题在于如何判断一个数不可能是快乐数,也就是循环何时停止的问题

        此时,我们就需要将判断过的和存储下来,每计算出一个新的和时,就去找在前面是否出现过,如果出现过,则说明是会无限循环的,那么这个数就不可能是快乐数,此时就返回false。

        那么我们需要快速查找之前是否出现过,显然哈希表会比数组的时间效率更高一些。(哈希表的基础知识见博客Leetcode刷题 由浅入深之哈希表——349. 两个数组的交集-CSDN博客)

class Solution {
public:bool isHappy(int n) {set<int> hash_list;while(n != 1){    //控制判断是否为快乐数int sum = 0;while(n){    //遍历每一位数字int b = n % 10;n = n / 10;sum = sum + pow(b, 2);    //计算每一位平方的和}n = sum;if(hash_list.find(n) != hash_list.end())return false;    //能找到则说明是无限循环,不可能是快乐数hash_list.insert(n);}return true;}
};

写法二(栈与列表)

解题思路:

解题思路与写法一相同,只是使用的数据结构略有不同。

(1)计算完数字的每一位,可以将其存储在栈中,再不断获取栈顶元素进行求平方的和。(此题可以不需要存储,这里只是练习一下栈结构的用法)

(2)在查询新的和在之前是否出现过时,可以采用循环遍历数组的查找方法。(采用写法一的哈希表会查找更快一些,不过使用简单的数组也是可以完成题目的)

class Solution {
public:bool isHappy(int n) {vector<int> list(0);stack<int> nums;while(n != 1){while(n){    //将每一位的数字存储在栈中nums.push(n % 10);n = n / 10;}while(!nums.empty()){n = n + pow(nums.top(), 2);nums.pop();}for(auto i : list){    //迭代器遍历查找元素if(i == n)return false;}list.push_back(n);}return true;}
};

(二)复杂度分析

时间复杂度

(1)写法一:

        内层while(n)循环每次迭代都会将n除以 10,其时间复杂度为 O(lg​n)

        外层while(n != 1)根据数学证明,不会无限进行下去。在最坏情况下,时间复杂度可以近似看作 O(lgn),因为每次计算新的n时,其位数大致以对数级别减少。

(位数与数值的对数关系:一个 k 位数 n 满足 10^{k-1} \leq n< 10^k,对不等式两边取以 10 为底的对数可得 k−1≤lgn<k,也就是 k≈lg​n。)

  set哈希法的查找和插入操作的平均时间复杂度为O(logk),其中kset中元素的数量。

综上,在最坏情况下,整体时间复杂度为O(lgn)

(2)写法二:

        内层while(n)循环每次迭代都会将n除以 10,其时间复杂度为 O(lg​n)

        内层while(!nums.empty())循环用于计算栈中元素的平方和,时间复杂度同样为 O(lgn)

        内层遍历vector数组看是否已经出现过,时间复杂度为 O(k)kvector中元素的数量。

        外层while(n != 1)循环会持续运行,直到出现重复。时间复杂度可以近似看作 O(logn)

综上,在最坏情况下,整体时间复杂度为O(klgn)

空间复杂度

(1)写法一:使用set<int>存储已经出现过的数字。在最坏情况下,set中会存储所有在计算过程中出现过的不同数字。因此,空间复杂度为O(lgn)

(2)写法二:使用vector<int>stack<int>stack在每次计算新的n时会存储n的每一位,其空间复杂度为 O(lgn)。vector用于存储已经出现过的数字,在最坏情况下,空间复杂度为 O(lgn)。因此,整体空间复杂度为O(lgn)

(三)总结

(1)set类型哈希法底层实现为红黑树,查找的时间复杂度会比暴力遍历低。(set类型哈希法知识见Leetcode刷题 由浅入深之哈希表——349. 两个数组的交集-CSDN博客)

(2)注意本题目当中循环求出整数n的每位数字的方法。

学习中,诚挚希望有心者指正和交流,经验或者方法都可。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com