You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

O(lg n)复杂度查找有序非降数组中唯一重复元素的Java算法求解

解题思路

本题要求时间复杂度为O(lg(n)),优先考虑二分查找方案,结合非降序数组的特性可按如下逻辑实现:

前提推导

  • 非降序数组中,重复出现2次的元素必定相邻
  • 结合题目唯一重复、数组长度为n的设定,符合该类算法题的通用隐含约束:数组元素取值范围为[1, n-1],除重复元素外其余值连续不重复,因此对于无重复的子区间[left, right],必然满足A[right] - A[left] == right - left(有序无重复整数的元素差值等于索引差值)
  • 若上述等式不成立,说明当前子区间存在重复元素,可据此收缩二分区间

Java 实现代码
public class FindDuplicate {
    public static int findDuplicate(int[] A) {
        int left = 0;
        int right = A.length - 1;
        while (left < right) {
            // 计算mid避免整数溢出
            int mid = left + (right - left) / 2;
            // 检查mid位置是否和相邻元素重复,命中直接返回
            if (A[mid] == A[mid + 1]) {
                return A[mid];
            }
            if (mid > 0 && A[mid] == A[mid - 1]) {
                return A[mid];
            }
            // 判断左半区间是否存在重复
            if (A[mid] - A[left] == mid - left) {
                // 左半区间无重复,搜索右半区间
                left = mid + 1;
            } else {
                // 左半区间存在重复,搜索左半区间
                right = mid;
            }
        }
        // 边界情况:重复元素在左右边界重合位置
        return A[left];
    }

    public static void main(String[] args) {
        // 测试用例
        int[] test1 = {1,2,3,3,4,5};
        System.out.println(findDuplicate(test1)); // 输出3
        int[] test2 = {2,2,3,4,5,6};
        System.out.println(findDuplicate(test2)); // 输出2
        int[] test3 = {1,2,3,4,5,5};
        System.out.println(findDuplicate(test3)); // 输出5
    }
}

代码说明
  • 无额外数据结构使用,仅用到3个临时索引变量,空间复杂度为O(1)
  • 每次二分将搜索区间缩小一半,时间复杂度严格满足O(lg(n))
  • 提前判断mid位置的相邻元素,大部分场景下可以提前命中返回,减少迭代次数
  • 没有使用任何Java内置的集合操作或查找函数,符合题目要求

内容的提问来源于stack exchange,提问作者FLY FOX 2058

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:18:04