LeetCode540

题目描述:

个人理解:

对于这个唯一数的下标一定为偶数,且左右两边都有偶数个数,数组长度为奇数。

所以使用二分查找能够更快速的找出唯一数。

当找到中间数(mid)时,需要判断mid和两边的数字是否相等。需要分情况进行:

* 当mid下标为奇数时,需要和前面一个数字相比较

* 当mid下标为偶数时,需要和后面一个数字相比较

判断后需要对左右两边界进行更新:

*当mid和前一个数字相等时,则缩小左边界(左边界为mid+1,因为mid左侧+1则为偶数个数) 
*当mid和后一个数字不相等时,则缩小右边界(右边界为mid,因为mid右侧一定是偶数个数)

mid的奇偶性判断:

用^判断,mid的值和前后的关系,当偶数^1时,为偶数+1,当奇数^1时,为奇数-1,这样就不需要判断mid的奇偶性,直接判断mid的值即可。

相等则缩小左边为mid+1

不相等则缩小右边为mid

array[mid] == array[mid^1]

源码(仅供参考):

import java.util.Scanner;

/**
 * ClassName:TestDemo
 * Package:Work540
 * Description:
 * 给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
 * 请你找出并返回只出现一次的那个数。
 * @date:2022/2/14 0:33
 * @author:HDLazy
 */
public class TestDemo {

    public static void main(String[] args) {

        Scanner scanner=new Scanner(System.in);

        System.out.println("输入数组大小");
        int arrayLength=scanner.nextInt();

        int [] array=new int[arrayLength];

        System.out.println("请输入"+arrayLength+"个整数");
        for(int i=0;i<arrayLength;i++){
            array[i]=scanner.nextInt();
        }

        System.out.print("数组是[");
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+"  ");
        }
        System.out.println("]");


        Solution solution=new Solution(array);

        int i = solution.singleNonDuplicate(array);

        System.out.println("不重复的数字是"+i);


    }
}

class Solution {

    private int[] array;

    public Solution(int []  array) {
        this. array= array;
    }


    //因为两个相同,所以在比较的时候,奇数就需要和前一个比,偶数就需要和后一个比(下标)
    public int singleNonDuplicate(int[] array) {
        int low = 0, high = array.length - 1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            if (array[mid] == array[mid^1]) {//异或1  偶数^1就是偶数+1  奇数^1就是奇数-1
                low = mid + 1;//左边界为mid+1
            } else {
                high = mid;//右边界为mid
            }
        }
        return  array[low];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值