繁体   English   中英

二分搜索 - 在给定数组中查找目标索引

[英]Binary Search - Find Index of Target in a Given Array

这是 leetcode 中二分查找的第一个问题。 我们被要求返回给定数组中目标的索引。 我对解决方案的第一次尝试如下:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int result = -1;
        for(int i = 0; i < nums.size(); i++){
            if (nums[i] == target)
                result = i;
          
        }
        return result;
    }
};

如果我没有两次放置返回结果,我会收到一条由于某种原因超时的消息。 无论如何,对于这段代码下面的数组和目标,它应该返回 4 时返回无意义的 16 值:

[-1,0,3,5,9,12]
9

我和一个朋友讨论过,他本着同样的精神想出了一个 Python 解决方案:

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        l = -1
        for i in nums:
            l += 1
            if i == target:
                print(l)
                return l

这个工作得很好。 不过,我看不出它与 C++ 中的有什么不同。 这在某种程度上与 Python 和 C 处理索引的方式有关吗? 为什么 C++ 解决方案不起作用? 对不起,如果这些都是非常愚蠢的问题,我一般对编程还很陌生。 欢迎任何帮助。

编辑:我将循环条件固定为i < nums.size()我以前没有注意到。 这解决了我遇到的时间超出问题,并允许我将返回值放在 for 循环之外,但是现在由于某种原因我得到了 6 的值。

编辑 2:将if语句修正为result = i ,解决了所有问题。 感谢 Mark 注意到这个非常愚蠢的错误。 现在一切都很好。 谢谢大家。

// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    std::cout.tie(NULL);
    return 0;
}();


// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>

using ValueType = std::uint_fast16_t;

static const struct Solution {
    static const int search(
        const std::vector<int>& nums,
        const int target
    ) {
        ValueType lo = 0;
        ValueType hi = std::size(nums) - 1;

        while (lo < hi) {
            ValueType mid = lo + (hi - lo) / 2;

            if ((nums[0] > target) ^ (nums[0] > nums[mid]) ^ (target > nums[mid])) {
                lo = mid + 1;

            } else {
                hi = mid;
            }
        }

        return lo == hi && nums[lo] == target ? lo : -1;
    }
};

  • 在 Python 中:
class Solution:
    def search(self, nums, target):
        if not nums:
            return -1
        lo, hi = 0, len(nums) - 1
        while lo <= hi:
            mid = (lo + hi) // 2
            if nums[mid] == target:
                return mid
            if nums[mid] >= nums[lo]:
                if nums[lo] <= target <= nums[mid]:
                    hi = mid - 1
                else:
                    lo = mid + 1
            else:
                if nums[mid] <= target <= nums[hi]:
                    lo = mid + 1
                else:
                    hi = mid - 1
        return -1
  • 这是 LeetCode 的官方解决方案之一,也有评论:
class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        def find_rotate_index(left, right):
            if nums[left] < nums[right]:
                return 0
            
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] > nums[pivot + 1]:
                    return pivot + 1
                else:
                    if nums[pivot] < nums[left]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
                
        def search(left, right):
            """
            Binary search
            """
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] == target:
                    return pivot
                else:
                    if target < nums[pivot]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
            return -1
        
        n = len(nums)
        
        if n == 0:
            return -1
        if n == 1:
            return 0 if nums[0] == target else -1 
        
        rotate_index = find_rotate_index(0, n - 1)
        
        # if target is the smallest element
        if nums[rotate_index] == target:
            return rotate_index
        # if array is not rotated, search in the entire array
        if rotate_index == 0:
            return search(0, n - 1)
        if target < nums[0]:
            # search on the right side
            return search(rotate_index, n - 1)
        # search on the left side
        return search(0, rotate_index)

  • Python 没有int溢出( mid = start + (end - start) // 2 )。 对于这个问题,LeetCode 的另一个官方解决方案是:
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        start, end = 0, len(nums) - 1
        while start <= end:
            mid = start + (end - start) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] >= nums[start]:
                if target >= nums[start] and target < nums[mid]:
                    end = mid - 1
                else:
                    start = mid + 1
            else:
                if target <= nums[end] and target > nums[mid]: 
                    start = mid + 1
                else:
                    end = mid - 1
        return -1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM