整数替换:将键盘输入的整数变成1,所用的最小次数 1)n是偶数,n=n/2 2)n是奇数,n=n-1/n=n+1 例如:7 -> 8 -> 4 -> 2 -> 1

初试:

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;
    }
}
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈年_H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值