算法题专栏:优选算法

一、快乐数

题目链接:快乐数

题目描述:

编写一个算法来判断一个数 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,如果为1,则证明是快乐数,反之证明不是快乐数;

解题代码:

java 复制代码
public boolean isHappy(int n) {
        if(n==1) return true;
        HashMap<Integer,Integer>map=new HashMap<>();
        while(true){
            map.put(n,map.getOrDefault(n,0)+1);
            if(map.get(n)!=1)return false;
            n=Calculatesquares(n);
            if(n==1) return true;
        }
    }

    private int Calculatesquares(int n) {
        if(n<10)return n*n;
        int sum=0;
        int flag=0;
        while(n>=10){
            flag=n%10;
            sum=flag*flag+sum;
            n=n/10;
        }
        return sum+n*n;
    }

解题思路二:采用 双指针

原因:这里的数平方相加之后会总是会形成一个循环,不会出现无限不循环的数。

所以:使用快慢指针,让快指针每次走两步,慢指针每次走一步,如果有重逢的数,判断重逢的数是否为1,如果为1,如果为1,则证明该数是快乐数,反之不是快乐数。

解题代码:

java 复制代码
        public int sum(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 fast= sum(n);
            int slow=n;
            while(fast!=slow){
                fast=sum(sum(fast));
                slow=sum(slow);
            }
            return slow==1;
        }

二、盛最多水的容器

题目链接:盛最多水的容器****

题目描述:

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

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

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

说明: 你不能倾斜容器。

解题思路一:暴力解法

每次固定左边的容器壁,接下来就一步步向右遍历,去求面积,最后获取最大的面积。暴力解法会导致超时!!!

解题代码:

java 复制代码
        public int maxArea(int[] height) {

            int tmp = 0;
            int max = 0;
            int n = height.length;
            for (int i = 0; i < n; i++) {
                int flag = 1;
                for (int j = i + 1; j < n; j++) {
                    if (height[j] <= height[i]) {
                        tmp = height[j] * flag;
                    } else {
                        tmp = height[i] * flag;
                    }
                    if (tmp > max) {
                        max = tmp;
                    }
                    flag++;
                }
            }
            return max;
        }

解题思路二:双指针

引用双指针,从数组的左右两边开始遍历。

假设:左边开始高度低于右边,那么此时就是以左边高度为基准算最大容器的最大面积。

  1. 左边低于右边,如果右边指针向左边移动,那么容器面积只会越来越小。

  2. 所以此时要去将左边指针向右移动,去找左边容器壁高于右边容器壁,以右边容器壁为基准算容器面积,此时才有可能比之前算的容器面积大。原因:指针移动过程中,左右之间的间隔会越来越小。

解题代码:

java 复制代码
    public int maxArea(int[] height) {
        int left =0;
        int right= height.length-1;
        int max=0;
        while(left<right)
        if(height[left]<height[right]){
            max=Math.max(max,(height[left])*(right-left));
            left++;
        }else{
            max=Math.max(max,(height[right])*(right-left));
            right--;
        }
        return max;
    }
相关推荐
没落之王5 小时前
三易五行看宋朝的三界确立
大数据·人工智能·算法
坤坤子吖5 小时前
算法学习——单调队列
开发语言·c++·笔记·学习·算法
Js.Tx7 小时前
【具体数学 Concrete Mathematics】2.1.5 一般性的方法
算法·具体数学
秋天的怀念_David8 小时前
算法一千零一夜 · 作品相关:版权与致谢声明
程序人生·算法·学习方法
图灵-M8 小时前
【数据结构】静态 & 动态顺序表
c语言·数据结构·笔记
揽星河..9 小时前
【C语言】数组
c语言·开发语言·算法
careathers9 小时前
【数据结构】基于比较的排序算法 - 选择排序
数据结构·算法·排序算法
听风若依9 小时前
C++模板初阶
c++·算法
纪念 22910 小时前
C++ 算法(模拟)
开发语言·c++·算法