初试:
import java.util.Scanner;
class 算法_整数替换 {
/*
将键盘输入的整数变成1,所用的最小次数
1)n是偶数,n=n/2
2)n是奇数,n=n-1/n=n+1
例如:7 -> 8 -> 4 -> 2 -> 1
*/
/*
踩坑解析
一、n是偶数直接除以2
二、n是奇数(优化:n+1或者n-1之后是偶数即可,
没必要管他哪个次数更少,最后结果取小的即可。)
1.n-1是2的次幂(降次更快)
2.n+1是2的次幂(降次更快)
3.n+1/n-1之后都不是2的次幂(没有分情况!!!)
1)n-1/2、n+1/2仍都是偶数,选择n-1
2)n-1/2仍是偶数,n+1/2不是偶数,选择n-1
3)n+1/2仍是偶数,n-1/2不是偶数,选择n+1
ps:只需要判断n+1/2仍是偶数,n-1/2不是偶数,即可。
*/
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int count = integerReplacement(n);
System.out.println("最少的次数为:"+count);
}
public static int integerReplacement(int n) {
int count =0;
for(int i=0;n!=1;i++){
if(n%2==0){//n是偶数
n=n/2;
count++;
}
else{//n不是偶数
for(int j=1; ;j++){
if((n-1)==Math.pow(2,j)){//n-1之后是2的次幂
n=n-1;
count++;
break;
}
else if((n+1)==Math.pow(2,j)){//n+1之后是2的次幂
n=n+1;
count++;
break;
}
else{//奇数n+1/n-1之后都不是2的次幂
//1)n+1/2,n-1/2之后都是偶数,选择n-1
//2)n+1/2之后不是偶数,n-1/2之后仍是偶数,选择n-1
//3)n+1/2之后仍是偶数,n-1/2之后不是偶数,选择n+1
if((n+1)/2%2==0&&(n-1)/2%2!=0){
n = n+1;
count++;
break;
}
else{
n = n-1;
count++;
break;
}
}
}
}
}
return count;
}
}
借鉴优化:
import java.util.Scanner;
class 算法_整数替换优化01 {
/*
踩坑解析
一、n是偶数直接除以2
二、n是奇数
不需要具体分情况,分别对n-1和n+1求次数,取小
*/
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int count = integerReplacement(n);
System.out.println("最少的次数为:"+count);
sc.close();
}
public static int integerReplacement(int n) {
int count = 0;
//对偶数进行预处理
while (n > 0 && n % 2 == 0){
count += 1;//偶数直接处理n / 2
n /= 2;
}
//然后处理两种特殊情况
if (n == 0){
return count + 1;
}
else if (n == 1){
return count;
}
else{
//最后分n + 1,n - 1进行两种处理
//不需要管当前奇数n+1好,还是n-1好,每次都取最小值,结果一定是最小的
count += Math.min(integerReplacement(n + 1), integerReplacement(n - 1));//奇数分别处理n + 1,n - 1取最小值
return count + 1;//+1或者-1都处理了一次
}
}
}
疑惑:
//难道是进程原因,第一个(n-1)有错
/* public static int integerReplacement(int n) {
int jia=0,jian=0,nn=0;
nn = n;//nn用于加,n用于减少
for(int i=0; ;i++){//n且nn等于1,结束循环
if(n<=1 || nn<=1)
break;
if(n%2==0||nn%2==0){//偶数:n/nn是偶数
if(n%2==0){//n是偶数
n = n/2;
jian++;
}
if(nn%2==0){//nn是偶数
nn = nn/2;
jia++;
}
}
if(n%2!=0||nn%2!=0){//奇数:n/nn是奇数
if(n%2!=0){//n是奇数
n = n-1;
jian++;
}
if(nn%2!=0){//nn是奇数
nn = nn+1;
jia++;
}
}
System.out.println(n+" "+nn);
}
System.out.println(jian+" "+jia);
return jia>=jian ? jian :jia;
}
}
*/