lintcode 刷题:457 经典二分查找问题

Posted 湾区人工智能

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lintcode 刷题:457 经典二分查找问题相关的知识,希望对你有一定的参考价值。

457 经典二分查找问题(找到任意一个就行)

数据结构和算法分析是程序员面试必考内容,接下来打算刷常见面试题,顺便分享给大家。刷,刷,刷,一般中级题目刷300道,刷3遍,国内大部分公司offer随便拿。想进顶级互联网公司,要刷一些高级题目,大概30%难度题目就行,想节省时间,个人推荐报个靠谱培训班。

内容目录

题目描述Python代码Java代码C++代码

题目描述

457 经典二分查找问题(找到任意一个就行)
描述
在一个排序数组中找一个数,返回该数出现的任意位置,如果不存在,返回-1

您在真实的面试中是否遇到过这个题?  
样例
给出数组 [1, 2, 2, 4, 5, 5].

对于 target = 2, 返回 1 或者 2.
对于 target = 5, 返回 4 或者 5.
对于 target = 6, 返回 -1.
挑战
O(logn) 的时间

英语描述

457 Classical Binary Search
Description
Find any position of a target number in a sorted array. Return -1 if target does not exist.

Have you met this question in a real interview?  
Example
Given [1, 2, 2, 4, 5, 5].

For target = 2, return 1 or 2.

For target = 5, return 4 or 5.

For target = 6, return -1.

Challenge
O(logn) time

Python代码

二分法解决

为什么要用 start + 1 < end?而不是 start < end 或者 start <= end?

A: 为了避免死循环。二分法的模板中,整个程序架构分为两个部分:

通过 while 循环,将区间范围从 n 缩小到 2 (只有 start 和 end 两个点)。
在 start 和 end 中判断是否有解。
start < end 或者 start <= end 在寻找目标最后一次出现的位置的时候,出现死循环。

Q: 为什么明明可以 start = mid + 1 偏偏要写成 start = mid?

A: 大部分时候,mid 是可以 +1 和 -1 的。在一些特殊情况下,比如寻找目标的最后一次出现的位置时,当 target 与 nums[mid] 相等的时候,是不能够使用 mid + 1 或者 mid - 1 的。因为会导致漏掉解。那么为了节省脑力,统一写成 start = mid / end = mid 并不会造成任何解的丢失,并且也不会损失效率——log(n) 和 log(n+1) 没有区别。

class Solution:
    """
    @param nums: An integer array sorted in ascending order
    @param target: An integer
    @return: An integer
    """

    def findPosition(self, nums, target):
        # write your code here
        if not nums or target is None:
            return -1

        start, end = 0, len(nums) - 1
        while start + 1 < end:
            mid = (end + start)//2
            if target < nums[mid]:
                end = mid
            elif target > nums[mid]:
                start = mid
            else:
                return mid

        if target == nums[start]:
            return start
        if target == nums[end]:
            return end 
        return -1

my_solution = Solution()
A = [122455]
target = 2
result = my_solution.findPosition(A, target)
print('result is',result)        
   

Java代码

/**
* 本参考程序来自九章算法,由 @九章算法 提供。版权所有,转发请注明出处。
* - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
* - 现有的面试培训课程包括:九章算法班,系统设计班,算法强化班,Java入门与基础算法班,android 项目实战班,
* - Big Data 项目实战班,算法面试高频题班, 动态规划专题班
* - 更多详情请见官方网站:http://www.jiuzhang.com/?source=code
*/
 

// version 1: with jiuzhang template
public class Solution {
    /**
     * @param A an integer array sorted in ascending order
     * @param target an integer
     * @return an integer
     */

    public int findPosition(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }

        int start = 0, end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }

        if (nums[start] == target) {
            return start;
        }
        if (nums[end] == target) {
            return end;
        }
        return -1;
    }
}

// version 2: without jiuzhang template
public class Solution {
    /**
     * @param A an integer array sorted in ascending order
     * @param target an integer
     * @return an integer
     */

    public int findPosition(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }

        int start = 0, end = nums.length - 1;
        while (start < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }

        if (nums[start] == target) {
            return start;
        }
        return -1;
    }
}

C++代码

/**
* 本参考程序来自九章算法,由 @九章算法 提供。版权所有,转发请注明出处。
* - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
* - 现有的面试培训课程包括:九章算法班,系统设计班,算法强化班,Java入门与基础算法班,Android 项目实战班,
* - Big Data 项目实战班,算法面试高频题班, 动态规划专题班
* - 更多详情请见官方网站:http://www.jiuzhang.com/?source=code
*/
 

class Solution {
public:
    /**
     * @param A an integer array sorted in ascending order
     * @param target an integer
     * @return an integer
     */

    int findPosition(vector<int>& A, int target) {
        // Write your code here
        int n = A.size();
        if (n == 0)
            return -1;
        if (A[n-1] < target || A[0] > target)
            return -1;

        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (A[mid] == target)
                return mid;
            if (A[mid] <= target) {
                l = mid + 1;
            } else
                r = mid - 1;
        }
        return -1;
    }
};


分享图片


决心和意志是学好编程的关键。
生命不息,刷题不止!
程序员之路,别怂,就是干!


print_r('关注一下吧');
var_dump('关注一下吧');
NSLog(@"关注一下吧!")
System.out.println("关注一下吧!");
console.log("点个赞吧!");
print("点个赞吧!");
printf("点个赞吧!");
cout << "点个赞吧!" << endl;
Console.WriteLine("转发一下吧!");
fmt.Println("转发一下吧!")
Response.Write("转发一下吧!");
alert(’转发一下吧!’)


以上是关于lintcode 刷题:457 经典二分查找问题的主要内容,如果未能解决你的问题,请参考以下文章

LintCode刷题---二分查找

LintCode刷题笔记-- LongestCommonSquence

二分查找模板Python实现

刷题--二分法

LintCode刷题笔记(九章ladder PartOne)--BugFree

LintCode 14. 二分查找