LeetCode初级算法之排序和搜索

[LeetCode]初级算法之排序和搜索

合并两个有序数组

Question:
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

Solution:
可以使用vector的insert函数来完成插入,我思想江化了直接又声明了一个vector,不可取不可取。

void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
       int i = 0, j = 0;
       vector<int> res;
       while(i < m && j < n)
       {
       	  if(nums1[i] < nums2[j])
       	  	res.push_back(nums1[i++]);
       	  else
       	  	res.push_back(nums2[j++]);
       }  
       for(;i < m; i++)
           res.push_back(nums1[i]);
       for(;j < n; j++)
           res.push_back(nums2[j]);
       nums1 = res;
    }

这题很简单,就这样~

第一个错误的版本

Question:
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:

给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。

Solution:
这题表面上看上来很简单,我从最后一个往前遍历不就好了嘛~~非也非也,题目说了,应该尽量减少对调用API的次数,那么我的第一个思路就是这道题可以看做一个查找的问题,我采用折半查找的方法来缩短时间复杂度,具体的思路就是递归调用,每次查找中间的产品版本,如果是对的,则递归调用后半部分, 否则调用前半部分。
一代目代码:
int firstBadVersion(int n) {
if(n <= 1) return n;
return firstBadVersion(1,n);
}
int firstBadVersion(int m, int n) {
if(n - m == 1) return n;
if(isBadVersion((n + m) / 2)) return firstBadVersion(m, (n + m) / 2);
else return firstBadVersion((n + m) / 2, n);
}
不出所料,超时!果然题目越简单,要求越高,那既然折半也不行,还有什么查找法呢。
查了网上的一些帖子,发现问题并没有出现在查找方法这里,查找的方法分为:

  1. 遍历查找
  2. 折半查找
  3. 散列查找

散列查找这里显然是不可行的,那折半查找的问题出在哪呢?仔细想一下,为啥会tle呢,因为我用的是
(m + n)/ 2 , m + n很可能会触犯题目要求的上界,所以我这里改成 m + (n - m) / 2 ,果不其然,通过啦!

bool isBadVersion(int version);
    int firstBadVersion(int n) {
    	if(n <= 1) return n;
    	return firstBadVersion(1,n);     
    }
    int firstBadVersion(int m, int n) {
    	if(n - m == 1) 
        {
            if(isBadVersion(m)) return m;
            return n;
        }
        int k = m + (n - m) / 2;
    	if(isBadVersion(k)) return firstBadVersion(m, k);
        else return firstBadVersion(k, n);     
    }

做这道题还是非常有趣的~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值