算法题

一、位运算

1、找出唯一成对的数

1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

/**
 * 题1:找出唯一成对的数
 * 1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
 * 每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
 *
 * 本题思路:
 *  利用异或的性质, x^i^i = x ,即将 1-1000 ^ arr[i]   (0<=i<1001),两两异或抵消,只留有一个重复的
 */

import java.util.*;

public class{
    public static void main(String[] args) {

        //首先创建数组
        int N = 1001;
        int[] arr = new int[N];
        for (int i = 0; i<arr.length;i++){
            arr[i] = i+1;
        }
        //最后一个数为随机数, Random().nextInt(-1) 生成的随机数为 [0-10),需要加1
        arr[arr.length-1] = new Random().nextInt(N-1)+1;
        int temp = 0;   //0 ^ x = x
        for (int i = 1;i<=N-1;i++){
            temp = temp ^ i; //将 1 ~ N-1 都异或一次,即 1^2^3……^999^1000
        }
        for (int i = 0;i<N;i++){
            temp = temp ^ arr[i]; //temp 原本的值为 1^2^3……^999^1000 ,然后再 ^ 1~1000 再加一个重复数,最后剩余重复数
        }
        System.out.println(temp);
    }

}

还有暴力解法,不过需要开辅助存储空间,与题意不同,但简单

/**
 * 题1:找出唯一成对的数
 * 1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
 * 每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
 *
 * 本题思路:
 *  利用异或的性质, x^i^i = x ,即将 1-1000 ^ arr[i]   (0<=i<1001),两两异或抵消,只留有一个重复的
 */

/**
 * 还有暴力解法,不过需要开辅助存储空间,与题意不同,但简单
 */

import java.util.*;

public class{
    public static void main(String[] args) {

        //首先创建数组
        int N = 1001;
        int[] arr = new int[N];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        //最后一个数为随机数, Random().nextInt(-1) 生成的随机数为 [0-10),需要加1
        arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;


        //        辅助空间方法
        int[] h = new int[N];
        for (int i = 0; i < N; i++) {
            //arr[i] 即 0-1000,有重复数, 原本h数组都是0,如果重复数是5,那 h[5]++ = 1;然后后来又发现了5,再 h[5]++ = 2,循环后找出结果为2的值的下标
            h[arr[i]]++;
        }
        for (int i = 0; i < N; i++) {
            if (h[i] == 2) {
                System.out.println(i);
            }
        }
    }

}

2、找出落单的那个数

一个数组里除了某一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字

此题比上题简单许多,还是利用异或,将所有数字异或,最后只剩下出现一次的数字

public class{
    public static void main(String[] args) {
        //下面数组只有1 出现一次
        int[] arr = {5, 6, 5, 6, 8, 8, 9, 9, 1, 2, 2};
        int temp = 0;
        for (int i = 0;i<arr.length;i++){
            temp = temp ^arr[i];
        }
        System.out.println(temp);
    }
}

3、二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
例: 9的二进制表示为1001,有2位是1

方法一:利用转换二进制查询

import java.util.Scanner;

/**
 * 二进制中1的个数
 * 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
 * 例: 9的二进制表示为1001,有2位是1
 */
public class{
    public static void main(String[] args) {

        int z = 0;
        Scanner scanner = new Scanner(System.in);

        int x = scanner.nextInt();
        //整数二进制最高32位
        int[] arr = new int[32];
        while (x > 0) {
            arr[z] = x % 2;
            z++;
            x = x / 2;
        }
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 1) {
                x++;
            }
        }
        System.out.println(x);

    }

}

方法二:利用位运算符,将 1 左移然后利用 & 做对比(或者将原数右移,再和 1 &)

在这里插入图片描述

 //方法二,利用位运算符
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        //输出二进制
        System.out.println(Integer.toString(N,2));
        int count = 0;
        for (int i =0;i<32;i++){
            if ((N&(1<<i)) == 1<<i){
                count ++;
            }
        }
        System.out.println(count);
    }

方法三:利用二进制中的借位减一,并和原数&,消去最低位的1

在这里插入图片描述

        //方法三
        int count = 0;
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        while(N!=0){
            N = (N-1)&N;
            count ++;
        }
        System.out.println(count);
    }

4、是不是2的整数次方

用一条语句判断一个整数是不是2的整数次方。

    public static void main(String[] args) {
        if (((8-1)&8) == 0){
            System.out.println("8是");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值