leetcode 540. 有序数组中的单一元
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例 1:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2:
输入: [3,3,7,7,10,11,11]
输出: 10
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
因为需要使用O(log n)时间复杂度和 O(1)空间复杂度,所以不能使用额外的空间来记录每个数字出现的频率,也不能使用异或来操作。不过条件给了排序。所以可以使用二分法。
1:若当前数字所在的索引是偶数,若它前面的数字都是出现两次的数字,则它和它后面的数字应该相同,否则他前面必定有一个数字出现了一次。
1:若当前数字所在的索引是奇数,若它前面的数字都是出现两次的数字,则它和它前面的数字应该相同,否则他前面必定有一个数字出现了一次。
为了防止边界判断,可以从1 到 (length - 2)范围内搜索。
public int singleNonDuplicate(int[] nums) { int length = nums.length; if (length == 1 || nums[0] != nums[1]) { return nums[0]; } if (nums[length - 1] != nums[length - 2]) { return nums[length - 1]; } int st = 1; int end = length - 2; while (st < end) { int m = st + ((end - st) >> 1); if ((m & 1) == 0) { if (nums[m] == nums[m + 1]) { st = m + 2; } else { end = m; } }else { if (nums[m] == nums[m - 1]) { st = m + 1; } else { end = m; } } } return nums[st]; }