题目描述:
给定一个正整数 n,你可以做如下操作:
1. 如果 n 是偶数,则用 n / 2替换 n。
2. 如果 n 是奇数,则可以用 n + 1或n - 1替换 n。
问:
n 变为 1 所需的最小替换次数是多少?
可见,该题的难点在于n是奇数时,应该是n+1还是n-1。
解法一:递归
当n==1时,return 0;
将int型的值传给m时,需要将m的类型申明为long long型。因为如果int 型的n为2147483647时,m=(n+1)/2的过程中n+1就会溢出。
int, long int都是4个字节的有符号数,最大值为2147483647.
可以将int型的实参传递给long long型的形参。
class Solution { public: int integerReplacement(long long n) { if(n==1) return 0; else if(n%2==0) return 1+integerReplacement(n/2); else { long long m=n+1; return 2+min(integerReplacement(m/2),integerReplacement((n-1)/2)); } } };
解法2:利用位运算
1 class Solution { 2 public: 3 int integerReplacement(long long n) { 4 int res=0; 5 while(n>3) 6 { 7 if(n%2) 8 { 9 n>>=1; 10 if(n%2) 11 { 12 n++; 13 //res++; 14 } 15 res+=2; 16 }//这一个if判断语句中包含了两种情况,举个例子:110111 首先初次判断为奇数,右移一位,相当于-1,再除以2 这时候res=2,n=011011,再次判断为奇数,+1,n=011100 这个结果与最初的n=110111先加1n=111000再右移1位是一样的n=011100 所以这样的操作以后res+=2; 17 //倘若最开始的n=1101,那么初次判断以后为奇数,-1,/2,此时n=0110就不用再进行加1操作了 //(n-1)/2 +1 ==(n+1)/2 18 else 19 { 20 n>>=1; 21 res++; 22 } 23 } 24 return res+n-1; 25 } 26 };
这道题有一定的技巧,感觉时间是在O(1)(菜鸡瞎猜的,这道题感觉是个脑力题,不仅要求对位运算熟悉,还要求要对整数的二进制表示很熟悉,在leetcode上击败了100%的c++用户,在时间上)
原文地址:https://www.cnblogs.com/yaggy/p/11336972.html
时间: 2024-11-10 15:41:39