『LeetCode|每日一题』---->整数替换

目录

每日一句

作者简介

 『LeetCode|每日一题』整数替换

1.每日一题

2.解题思路 (枚举法)

        2.1 思路分析

        2.2 核心代码

        2.3 完整代码

        2.4 运行结果 

3.解题思路(记忆化搜索)

        3.1 思路分析

        3.2 核心代码

        3.3 完整代码 

        3.4 运行结果

4.解题思路(贪心) 

        4.1 思路分析

        4.2 核心代码 

        4.3 完整代码

        4.4 运行结果

5.总结


每日一句

你可以随时转身,但不能一直后退

作者简介

🏡个人主页:XiaoChen_Android

📚学习专栏:力扣专栏

🕒发布日期:2022/8/30

在这里插入图片描述

 『LeetCode|每日一题』整数替换

1.每日一题

原文链接--->点我

2.解题思路 (枚举法)

        2.1 思路分析

刚开始看到这题,我就在草稿本上写出来一系列的数及对应的替换方法,发现了一些规律

        S1:如果该数为1,那么返回0即可;

        S2:如果该数为偶数,那么该数除以二的同时替换方法数+1即可;

        S3:如果该数是奇数的话,我们可以看成两个偶数,这两个数为\frac{n - 1}{2}\frac{n + 1}{2},用这两个数递归调用函数,取小的那个值,然后最后的结果加上2就行

        2.2 核心代码

        if (n % 2 == 0) return 1 + integerReplacement(n / 2);
        return 2 + Math.min(integerReplacement(n / 2), integerReplacement(n / 2 + 1));

        2.3 完整代码

class Solution {
    
    public int integerReplacement(int n) {
        if (n == 1) return 0;
        if (n % 2 == 0) return 1 + integerReplacement(n / 2);
        return 2 + Math.min(integerReplacement(n / 2), integerReplacement(n / 2 + 1));
    }
}

        2.4 运行结果 

由结果可以看出,此方法时间复杂度和空间复杂度都还可以进一步优化,下面将介绍另外的方法 

3.解题思路(记忆化搜索)

        3.1 思路分析

思路和第一种方法类似,就是增加了一个HashMap来记录已经计算过的值,如果该数没有被计算过,那么就把他的值以及整数替换方法数添加进map,这样大大减少了时间的消耗

        3.2 核心代码

        if(map.containsKey(n) == false){
            if(n % 2 == 0){
                map.put(n , 1 + integerReplacement(n / 2));
            }else {
            map.put(n , 2 + Math.min(integerReplacement(n / 2) , integerReplacement(n / 2 + 1)));
            }
        }

        3.3 完整代码 

class Solution {
    
    Map<Integer , Integer> map = new HashMap<Integer , Integer>();

    public int integerReplacement(int n) {
        if (n == 1) return 0;
        if(map.containsKey(n) == false){
            if(n % 2 == 0){
                map.put(n , 1 + integerReplacement(n / 2));
            }else {
            map.put(n , 2 + Math.min(integerReplacement(n / 2) , integerReplacement(n / 2 + 1)));
            }
        }
        return map.get(n);
    }
}

        3.4 运行结果

 通过对比上一个方法可以看出时间消耗明显减少,所以用HashMap可以减少计算次数

4.解题思路(贪心) 

        4.1 思路分析

        S1:分两种情况讨论:

  1. 如果该数除二求余为0,那么只有一种方法能获得最少的替换次数;
  2. 如果该数除二求余不为0,那么又可以分三种情况:
    1. n % 4 == 1时:我们应将该数变为\frac{n - 1}{2},假设变为\frac{n + 1}{2},奇数加一除以二还是奇数,\frac{n + 1}{2}还是奇数,如果下一步是-1再除以2,则变成了\frac{n - 1}{4},实际上还是相当于\frac{n - 1}{2} 除以2;如果下一步是+1再除以2,则变成了\frac{n + 3}{4}, 实际上相当于\frac{n - 1}{2} 除以2再加1;因此得出将该数变为\frac{n - 1}{2} 的结果总是不会差于\frac{n + 1}{2} ;
    2. n % 4 == 3时:我们应该将该数变为\frac{n + 1}{2},假设变为\frac{n - 1}{2} ,\frac{n - 1}{2} 还是个奇数,如果下一步是-1再除以2,则变成了\frac{n - 3}{4},实际上还是相当于\frac{n + 1}{2} 除以2再-1;如果下一步是+1再除以2,则变成了\frac{n + 1}{4},实际上相当于\frac{n + 1}{2}除以2;因此得出将该数变为\frac{n + 1}{2}的结果总是不会差于\frac{n - 1}{2} ;
    3. 此情况为特殊情况,如果此时n == 3,那么\frac{n - 1}{2}等于1,就不需要考虑其他情况,直接变成\frac{n - 1}{2}即可; 

        3.该方法只需要一个循环即可,只要n != 1时就可以继续循环,额外定义一个变量存替换次数即可

        4.2 核心代码 

        while(n != 1){
            if(n % 2 == 0){
                ans += 1;
                n /= 2;
            }else if(n % 4 == 1){
                ans += 2;
                n = n / 2;
            }else {
                if(n == 3){
                    ans += 2;
                    n = 1;
                }else {
                    ans += 2;
                    n = n / 2 + 1;
                }
            }
        }

        4.3 完整代码

class Solution {
    public int integerReplacement(int n) {
        int ans = 0;
        if(n == 1) return 0;
        while(n != 1){
            if(n % 2 == 0){
                ans += 1;
                n /= 2;
            }else if(n % 4 == 1){
                ans += 2;
                n = n / 2;
            }else {
                if(n == 3){
                    ans += 2;
                    n = 1;
                }else {
                    ans += 2;
                    n = n / 2 + 1;
                }
            }
        }
        return ans;
    }
}

        4.4 运行结果

5.总结

我认为记忆化搜索更容易被人理解,当然贪心算法和记忆化搜索的时间复杂度也是O(log n),相比第一种方法都大大节省了时间的消耗,贪心算法没有用递归,所以也是高效率的解法


🍁 类似题目推荐: 

1.数据结构基础

2.算法专项练习 

3.剑指offer专项练习

4.推荐一个学习网站:LeetCode,算法的提升在于日积月累,只有每天练习才能保持良好的状态

如果文章对各位大佬有帮助就支持一下噢,新手尝试,不好的地方请各位大佬多多指教!   

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值