LeetCode(算法入门题单——二分查找,双指针部分)

开刷算法部分,最近要加快进度了,填一填上学期数据结构没有期末考试的深坑


二分查找:1天

比较机械模板的查找方法


704. 二分查找

难度简单881收藏分享切换为英文接收动态反馈

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1


示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

最基本的二分查找模板

class Solution {
public:
    int search(vector<int>& nums, int target) 
	{
		int	left=0,right=nums.size()-1;
		while(left<=right)
		{
			int	mid=(right-left)/2+left;
			int	num=nums[mid];
			if(num==target)
			{
				return	mid;
			}
			else	if(num>target)
			{
				right=mid-1;
			}
			else	
			{
				left=mid+1;
			}
		}
		return	-1;
    }
};

278. 第一个错误的版本

难度简单735收藏分享切换为英文接收动态反馈

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例 1:

输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false 
调用 isBadVersion(5) -> true 
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。

示例 2:

输入:n = 1, bad = 1
输出:1

提示:

  • 1 <= bad <= n <= 231 - 1

对二分查找的一个简单应用,题解给出的方法是逐步逼近,最后right==left时返回结果

我写的就要笨一些,直接进行彻底的二分查找(即仍旧是left<=right的判断条件)

当满足出现true和false的分界点时返回结果

// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) 
    {
        int left=1,right=n;
        while(left<=right)
        {
            int mid=(right-left)/2+left;
            if(isBadVersion(mid)==1)
            {
                if(isBadVersion(mid-1)==0)
                    return mid;
                else
                    right=mid-1;
            }
            else
                left=mid+1;
        }
        return 1;
    }
};

 

35. 搜索插入位置

难度简单1612收藏分享切换为英文接收动态反馈

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 为 无重复元素 的 升序 排列数组
  • -104 <= target <= 104

 写了个大补丁代码...

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) 
    {
        int left=0,right=nums.size()-1;
		while(left<=right)
		{
            //没有相等的数字返回插入位置
			if(right==left&&nums[left]<target)  //当目标大于位置数时,插入到后面
				return left+1;
            else if(right==left&&nums[left]>target)
                return left;
            
			int mid=(right-left)/2+left;
			int num=nums[mid];
			if(num==target)
				return mid;
			else	if(num<target)
				left=mid+1;
			else	if(mid-1<left)  //防止出现right一下子小于left,导致掠过插入情况
				right=left;
            else 
                right=mid-1;
		} 
		return -1;
    }
};

 

977. 有序数组的平方

难度简单570收藏分享切换为英文接收动态反馈

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题

 通过两个指针,从前后两个方向依次遍历数组,比较绝对值大小选小的先放入答案数组

ps:双指针写下来运行速度没有排序快多少有些离谱哦...

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) 
	{
		vector<int>ans(nums.size());
		int p1=0,p2=nums.size()-1;
        int count=p2;
		while(p1<=p2)
		{
			if(nums[p1]>=0)
				ans[count--]=pow(nums[p2--],2);
			else	if(nums[p2]<0)
				ans[count--]=pow(nums[p1++],2);
			else	if(-nums[p1]>=nums[p2])
				ans[count--]=pow(nums[p1++],2);
			else	if(-nums[p1]<nums[p2])
				ans[count--]=pow(nums[p2--],2);
		}
		return	ans;
    }
};

 

189. 轮转数组

难度中等1526收藏分享切换为英文接收动态反馈

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

进阶:

  • 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

解法一: 使用额外的数组

想到了取余,但跟题解写的比起来就太愚蠢了...

class Solution {
public:
    void rotate(vector<int>& nums, int k) 
    {
    	int n=nums.size();
        k=k%n;
		vector<int>ans(n);
		for(int i=k;i<n;i++)
		{
			ans[i]=nums[i-k];
		}
		for(int i=0;i<k;i++)
		{
			ans[i]=nums[i+(n-k)];
		}
		nums=ans;
    }
};

题解:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> newArr(n);
        for (int i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i];
        }
        nums.assign(newArr.begin(), newArr.end());
    }
};

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode-solution-nipk/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值