给定一个长度为 n 的有序数组,其中每个元素都出现两次,只有一个数仅出现一次。请你找出这个数。
你能在O(logn)的时间复杂度和O(1)的 空间复杂度下完成本题吗
输入
[1,2,2,3,3]
输出
1
简单写法 每次跳跃2个位置 两两比较
public class Test {
public int singleNonDuplicate(int[] nums) {
int n=nums.length;
for (int i = 0; i <nums.length ; i+=2) {
if(i==n-1){
return nums[i];
}
if(nums[i]!=nums[i+1]){
return nums[i];
}
}
return -1;
}
public static void main(String[] args) {
int[]nums=new int[]{1,1,2,3,3,4,4,8,8};
int res=new Test().singleNonDuplicate(nums);
System.out.println(res);
}
}
利用二分查找的写法
package com.example.demo1.service.impl;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
public int singleNonDuplicate(int[] nums) {
int left=0;
//二分查找 可能会找到最后的一个位置上 所以长度减去1
int right=nums.length-1;
while (left<right){
//获取中间的位置
int mid=(left+right)/2;
//如果中间值是偶数
if(mid%2==0){
//判断中间值索引位置的数据 和 右边的数据是否相等
if(nums[mid]==nums[mid+1]){
//如果相等 那么左边的位置 往右边移动
left=mid+1;
}else {
//如果不相等 那么右边的结束位置 从中间开始
right=mid;
}
}else {
//如果中间的位置是奇数 那么判断 中间的数据和左边的元素是否一致
if(nums[mid]==nums[mid-1]){
//如果一致 那么左边的位置 往右边移动
left=mid+1;
}else {
//如果不相等 那么右边的结束位置 从中间开始
right=mid;
}
}
}
//最后返回left 或者right 都行 因为肯定有一个索引位置的数据 是不匹配的
return nums[right];
}
public static void main(String[] args) {
int[]nums=new int[]{1,1,2,3,3,4,4,8,8};
int res=new Test().singleNonDuplicate(nums);
System.out.println(res);
}
}