当前位置: 首页 > 知识库问答 >
问题:

二进制搜索O(log n)算法在顺序列表中查找重复?

邢永安
2023-03-14

有人知道一种比线性算法更快地在顺序数字列表中找到重复吗?我现在在Java工作,但任何语言或伪代码都可以。

例如,给定此int[]输入:

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 7 | 8 | 9

输出将是索引或值“7”。

我知道在O(n)线性时间的明显遍历,但我正在尝试通过在O(log n)时间的二进制搜索来查看这是否可能。

共有3个答案

席兴平
2023-03-14
public class DuplicateNumber {

    public int findDuplicateNumber(List<Integer> numbers){

        int highestNumber = numbers.size() - 1;
        int total = getSum(numbers);
        int duplicate = total - (highestNumber*(highestNumber+1)/2);
        return duplicate;
    }

    public int getSum(List<Integer> numbers){

        int sum = 0;
        for(int num:numbers){
            sum += num;
        }
        return sum;
    }

    public static void main(String a[]){
        List<Integer> numbers = new ArrayList<Integer>();
        for(int i=1;i<30;i++){
            numbers.add(i);
        }
        //add duplicate number into the list
        numbers.add(22);
        DuplicateNumber dn = new DuplicateNumber();
        System.out.println("Duplicate Number: "+dn.findDuplicateNumber(numbers));
    }
}
呼延卓
2023-03-14

请注意,二进制搜索适用于排序列表。因此,如果您有一个具有重复项的排序列表,则二进制搜索只有在您的重复项相邻时才有用。相邻的重要性是为了您可以测试键在找到的键的上一个和下一个位置的存在。任何其他尝试在未排序列表上使用二进制搜索的方法都会给出不正确的结果。

这里有一些代码来说明我的意思

import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        int[] list = {1, 2, 3, 4, 5, 6, 7, 7, 8, 9 };
        int key = 7;
        int result = Arrays.binarySearch(list, key);
        System.out.println(result);
        if( list[result+1] == key  || list[result-1] == key )
                System.out.println("yes we have a duplicate.");
    }
}

如果中的比较是O(1),我们仍然使用二分搜索的O(logn)。

柳晔
2023-03-14

如果您假设数字必须从0开始并增加1,则可以将中间值与索引进行比较。如果中间位置相同,就往上走;如果中间位置不一样,就往下走。

这将为您提供二分查找时间O(log2 N)。唯一的区别是您正在与索引进行比较,而不是固定值。

public static void main(String... args) {
    int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9};
    int duplicate = findDuplicate(array);
    System.out.println(duplicate);
}

private static int findDuplicate(int[] array) {
    int low = 0;
    int high = array.length - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = array[mid];

        if (midVal == mid)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return high;
}
 类似资料:
  • 我有一个严格按递减顺序排序的数组和一个元素;我想找到数组中最大元素的索引,该元素小于val(如果val已经存在,则为相等),并且我想在时间内完成此操作。和执行upper_bound()不是一个选项。 例如,如果数组为{10,5,3,1}而val为6,则函数应返回1。 我对迭代器是个新手,尝试过在upper_bound()中添加比较函数来使其工作,但失败了。我该怎么处理这件事。 注意:我检查了类似的

  • 我使用这个二进制搜索函数得到一个较大数据集的索引错误。当我输入一个较小的数据集时,即[1,2,3,4,5]搜索5。算法按预期运行。但是,当我获取下面的文本时,使用空参数列表(delimeter char为“”)调用string对象的split方法,并将字符串拆分为列表值,其中每个元素都是字符串,然后搜索单词“culpa”,我最终会出现以下错误: 索引错误:列表索引超出范围 非常感谢你的帮助。非常感

  • 我有一个二进制搜索树,它的每个节点都有两个值。 所以它的节点是这样的。 我已经根据节点的“name”变量的升序在BST中插入了值。所以树的顺序遍历将按“name”的升序返回节点。 现在我想根据“值”变量的升序显示树节点。无需更改原始树。哪种算法/方法对此最有效?

  • 给定二叉查找树(BST)和整数val的根。 在BST中找到该节点的值等于val的节点,并返回以该节点为根的子树。如果这样的节点不存在,则返回null。 为什么'ans=root'不起作用??

  • 主要内容:顺序查找算法的实现思路,顺序查找算法的具体实现顺序查找算法又称 顺序搜索算法或者 线性搜索算法,是所有查找算法中最基本、最简单的,对应的时间复杂度为 。 顺序查找算法适用于绝大多数场景,既可以在有序序列中查找目标元素,也可以在无序序列中查找目标元素。 顺序查找算法的实现思路 所谓顺序查找,指的是从待查找序列中的第一个元素开始,查看各个元素是否为要找的目标元素。 举个简单的例子,采用顺序查找算法在 {10,14,19,26,27,31,33,3

  • 主要内容:顺序查找的实现,顺序查找的性能分析,总结通过前面对静态 查找表的介绍,静态查找表即为只做查找操作的查找表。 静态查找表既可以使用顺序表表示,也可以使用链表结构表示。虽然一个是数组、一个链表,但两者在做查找操作时,基本上大同小异。 本节以静态查找表的顺序存储结构为例做详细的介绍。 顺序查找的实现 静态查找表用顺序存储结构表示时,顺序查找的查找过程为:从表中的最后一个数据元素开始,逐个同记录的关键字做比较,如果匹配成功,则查找成功;反之,如