397_整数替换_2021.11.19

给定一个正整数 n ,你可以做如下操作:

如果 n 是偶数,则用 n / 2替换 n 。
如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。
n 变为 1 所需的最小替换次数是多少?

 

 

 

一开始我个人的思路就是暴力法递减赋值,但是这一题有三个情况需要说明:

①需要找出什么时候应该是n+1什么时候应该是n-1

②在我本人的逻辑之上当出现元素“3”的时候需要另行判断

③给定数值越界怎么办

所以,在①之前,我设计的三元表达式是:

 n = (n % 2) == 0 ? n / 2 : n - 1; 
 
但是这样明显无法求出最优解,所以我观察了一下,相邻的三次循环所得到的n不能都为 奇数——偶数——奇数 这样的情况。
例如:第一次是617,我如果取(617+1)= 618, 第二次偶数618除以2之后得到了309,那我就不会这样取,我会取(617-1)= 616 第二次偶数616除以2得到的情况是306,这就保证了三次循环中出现的次数为 奇数——偶数——偶数
不符合第一种情况,所以可以继续下去。
所以就衍生出了下面的三元表达式:
 n = (n % 2) == 0 ? n / 2 : (((n - 1) / 2) % 2) == 0 ? n - 1 : n + 1; 

但是这种情况下就出现了②所违背的情况,因为明显在n=3时,取n-1=2,(n-1)/2=1这种两步走的情况符合实际最优步数,但是在上述代码中给定的方法会因为初始传入参数为奇数,且二次循环后得到的结果也为奇数而出现n = n+1,此时n = 4这种情况,最优步数为3次,这种时候我就直接另行判断了,加了 特殊情况3,即有了下面的代码:

 n = (n % 2) == 0 ? np / 2 : (((np - 1) / 2) % 2) == 0 || np == 3 ? np - 1 : np + 1; 

最后,在测试过程中,测试例子会给出一个超越int大小的数字,从而导致数值越界情况,这里我就直接把初始数字赋值给了unsigned int,以下是最终代码:

 1 #define  _CRT_SECURE_NO_WARNINGS
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Solution {
 6 public:
 7     // 纯暴力法,要单独考虑3的情况
 8     int integerReplacement(int n) {
 9 
10         unsigned int np = n;
11         int calNum = 0;
12 
13 
14         while (np != 1) {
15 
16             np = (n % 2) == 0 ? n / 2 : (((n - 1) / 2) % 2) == 0 || n == 3 ? n - 1 : n + 1;
17             calNum++;
18         }
19 
20         return calNum;
21     }
22 };
23 
24 
25 int main(void)
26 {
27     Solution s;
28     cout << s.integerReplacement(2147483647) <<endl;
29 
30     getchar();
31     return 0;
32 }

 

在查看题解之后,我这个算是代码简化版的贪心算法,题解贪心算法如下:

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

想到其他算法的小伙伴可以一起交流。

 

 

posted @ 2021-11-19 10:16  炫迈吃到爽  阅读(45)  评论(0编辑  收藏  举报