代码随想录算法训练营第一天| 数组 704. 二分查找、27. 移除元素

数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合,今天刚学习了操作系统的相关知识,也放进来,为了使的CPU缓存命中率高,尽量保证数组连续

要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。

数组的元素是不能删的,只能覆盖。

704. 二分查找

看到题目的第一想法是暴力解法,但仔细一看发现数组是有序的,加上题目提示有二分查找,然后想到一个数除以2包含了奇数与偶数,先考虑一下奇数偶数的情况,然后再分析是否需要区分奇数偶数。二分法这里还需要注意的前提是再有序数组中使用。

还需要考虑循环以及退出循环操作,最开始想使用while(nums[tmp]!=target)然后发现不可行,因为进行多次二分查找后,无法比较好的表示左右区间。想到定义left和right进行解决。因此,首先想到的循环条件为while(left<right),然后想终止条件,虽然能跑出来,但是感觉是按照答案写题目了,会卡在循环终止的情况下。

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

看了一下解析,发现不必死死地卡在right=tmp上,因为本来就不相等,可以往前移一位。

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

需要理解并掌握二分法的相关知识,写二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量。二分法包含了两种情况,一种是左闭右开区间,还有一种是左闭右闭区间,上面这种做法属于左闭右开区间这种情况,因为right是无法取到的,只有[left,right),所以left不可以等于right,由于是左闭右开区间,进行下一次循环时,right还是无法取到,所以right不用-1,而left需要+1。同理,可以理解左闭右闭区间的情况。

27. 移除元素

//用双指针的方法,使用一个快指针核一个慢指针,快指针指向新数组所需要的元素。新数组的坐标值应该使用慢指针
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow{0};
        for(int fast{0};fast<nums.size();fast++){
            if(nums[fast]!=val){
                nums[slow]=nums[fast];
                slow++;
            }
        }
        //最后输出不需要++slow,因为前面已经slow++了,说明以及那个大一位了
        return slow;
    }
};

// 传统的暴力法
/*class Solution {
public:
	int removeElement(vector<int>& nums, int val) {
		int len = nums.size();
		for (int i = 0; i < len; i++)
		{
			int flag = 0;
			if (nums[i] == val)
			{
				for (int j = i; j < len && nums[j] == val; j++)
				{
					flag++;
				}
				len -= flag;
				for (int j = i; j < len; j++)
				{
					nums[j] = nums[j + flag];
				}
			}
		}

		return len;
	}
};*/

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第二十二天的算法训练主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值