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

使用二分搜索查找旋转点,为什么要和第一个元素比较?

雷方伟
2023-03-14

所以我有这个问题,我购买的面试准备课程,我有解决办法,在这里,以及。我知道我们在用二分搜索找到目标。数组包含不同的单词,目标是以。我最初的方法是比较i-l和i+1。如果i-1比i大,i+1比i小,那么我们就知道i是目标。但解决办法是做一些我不明白的事。问题就在这里

我把字典翻到中间的一页,开始翻阅,寻找我不认识的单词。我把我不认识的每个单词放在我在内存中创建的一个巨大数组中增加索引。当我读到字典的结尾时,我从头开始,做同样的事情,直到我读到我开始读的那一页。

现在我有一组单词,大部分是按字母顺序排列的,除了它们从字母表中间的某个地方开始,到达末尾,然后从字母表的开头开始。换句话说,这是一个按字母顺序排列的数组,被“旋转”了。例如:

String[] words = new String[]{
        "ptolemaic",
        "retrograde",
        "supplant",
        "undulate",
        "xenoepist",
        "asymptote",  // <-- rotates here!
        "babka",
        "banoffee",
        "engender",
        "karpatka",
        "othellolagkage",
};
  public static int findRotationPoint(String[] words) {
    final String firstWord = words[0];

    int floorIndex = 0;
    int ceilingIndex = words.length - 1;

    while (floorIndex < ceilingIndex) {

        // guess a point halfway between floor and ceiling
        int guessIndex = floorIndex + ((ceilingIndex - floorIndex) / 2);

        // if guess comes after first word or is the first word
        if (words[guessIndex].compareTo(firstWord) >= 0) {
            // go right
            floorIndex = guessIndex;
        } else {
            // go left
            ceilingIndex = guessIndex;
        }

        // if floor and ceiling have converged
        if (floorIndex + 1 == ceilingIndex) {

            // between floor and ceiling is where we flipped to the beginning
            // so ceiling is alphabetically first
            break;
        }
    }

    return ceilingIndex;
}

为什么我们要和字[0]做比较?我们知道单词[0]不是目标,因为它被移动了。假设我们有p,r,s,u,x,a,b,c,e,k,O。我们知道a是中间。自p>a起,我们将上限设为a。然后我们再比较p和S。所以它错过了目标。我就是不明白这一点。如有任何帮助,我将不胜感激

共有1个答案

松骏俊
2023-03-14

这样做是为了了解,旋转点在哪里。

让我们看看你的例子:

String[] words = new String[]{
    "ptolemaic",
    "retrograde",
    "supplant",
    "undulate",
    "xenoepist",
    "asymptote",  // <-- rotates here!
    "babka",
    "banoffee",
    "engender",
    "karpatka",
    "othellolagkage",
};

比较字[0](即托勒密)和字[guessIndex](即渐近)将告诉您数组的旋转/移位方向。

[1 2 3 4 5 6 7] // no rotation

[6 7 1 2 3 4 5] // biggest is left to the center

[2 3 4 5 6 7 1] // smallest is right to the center
 类似资料:
  • 主要内容:src/runoob/binary/BinarySearchTreeSearch.java 文件代码:二分搜索树没有下标, 所以针对二分搜索树的查找操作, 这里定义一个 contain 方法, 判断二分搜索树是否包含某个元素, 返回一个布尔型变量, 这个查找的操作一样是一个递归的过程, 具体代码实现如下: ... // 查看以node为根的二分搜索树中是否包含键值为key的节点, 使用递归算法 private boolean contain (Node node, Key key )

  • Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its in

  • 这种方法在确定树是否为BST时是错误的吗?节点的左子树仅包含键小于节点键的节点。节点的右子树仅包含键大于节点键的节点。左右子树也必须是二叉搜索树。我的代码是:

  • 问题内容: 我想找到相应的span元素。我想使用css选择器检查span元素的顺序。因此,当我使用Selenium IDE时,我将按照以下方式进行验证(使用第n个子概念)。 verifyText | css = .title:nth(0)| 首页 verifyText | css = .title:nth(1)| 帖子 verifyText | css = .title:nth(2)| 事件 ve

  • 我正在编写一个函数,该函数应该删除链表的最后一个元素 这是我对节点的定义 我有一个节点列表1,它为值1、2、3运行了3次insert函数 insert函数如下所示 现在我的delete_last_element函数如下所示 基本上,我的想法是,我会先看看第一个元素是否为空,如果是,我什么也不做,因为没有最后一个元素。然后我将curr设置为head->next以查看列表中的下一个元素,如果它为nul

  • 同时研究。net,我碰到了SpinLock和SpinWait。从表面上看,在我看来,SpinWait将永远是一条出路..当线程实际上必须等待来自线程外部的信号时,为什么还要继续忙碌等待而不放弃CPU呢?在这些空闲等待中花费的周期可能已经被线程使用,该线程可能会发出信号并释放正在忙碌等待的线程。 为什么会存在SpinLock?它与使用while循环的简单忙等待有什么不同?在什么情况下会想使用Spin