题目描述:
个人理解:
对于这个唯一数的下标一定为偶数,且左右两边都有偶数个数,数组长度为奇数。
所以使用二分查找能够更快速的找出唯一数。
当找到中间数(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];
}
}