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

学习时间:
09.21 9:30 -3:00
704.二分查找
题目信息:
1.有序(升序)整型数组
2.查找target
初步解题思路:
遍历,查找,返回

class Solution {

public:

    int search(vector<int>& nums, int target) {

        for(int i = 0; i<nums.size();i++){

            if(nums[i] == target){

                return i;

            }

        }

        return -1;

    }

};

代码随想录学习
二分法解题思路
1.边界
一般为左闭右开/左闭右闭
[left, right] 
判断:通过区间的合法性选择 <= 还是<
2.区间二分
target> middle 取右区间
target<middle 取左区间
3.区间边界
middle-1;左闭右闭时用过middle的值所以为middle-1;
自写代码:

class Solution {

public:

    int search(vector<int>& nums, int target) {

        int left = 0;

        int right = nums.size()-1;

        while(left<=right){

            int middle = (left+right)/2;

            if(target<nums[middle]){

                right = middle-1;

            }else if(target>nums[middle]){

                left = middle+1;

            }else return middle;

        }

        return -1;

    }

};

看网站代码查漏补缺:

int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
第二种写法:

class Solution {

public:

    int search(vector<int>& nums, int target) {

        int left = 0;

        int right = nums.size();

        while(left < right){

            int middle = left +(right-left)/2;

            if(target>nums[middle]){

                left = middle +1;

            }else if (target<nums[middle]){

                right = middle;

            }else return middle;

        }

        return -1;

    }

};

35.搜索插入位置

题目信息:
1.排序数组
2.查找target返回索引
3.不存在返回插入位置
解题思路:
遍历,查找,返回

class Solution {

public:

    int searchInsert(vector<int>& nums, int target) {

        

        for(int i = 0 ; i<nums.size();i++){

        if(nums[i]>=target){

            return i;

        }}

        return nums.size();

    }

};

二分法:

class Solution {

public:

    int searchInsert(vector<int>& nums, int target) {

        int left = 0;

        int right = nums.size()-1;

        while(left <= right){

            int middle = left+(right-left)/2;

            if(target>nums[middle]){

                left = middle +1;

            }else if (target<nums[middle]){

                right = middle-1;

            }else return middle;

        }

     return right+1;

    }

};

27.移除元素

1.无序数组
2.数组内数值有重复
3.查找val数量删除
4.时间复杂度o(n)
第一次解题

class Solution {

public:

    int removeElement(vector<int>& nums, int val) {

        int length = nums.size();

        for(int i =0 ; i <nums.size();i++){

            if(nums[i] == val){

                length--;

            }

        }

        return length;

    }

};

问题内数组是引用,return的是数组,返回的是nums[length],所以要进行val覆盖

双指针法

class Solution {

public:

    int removeElement(vector<int>& nums, int val) {

        int slowIndex =0; 

        for(int fastIndex = 0 ;fastIndex < nums.size();fastIndex++){

            if(val != nums[fastIndex]){

                nums[slowIndex++] = nums[fastIndex];

            }

        }

        return slowIndex;

    }

};

34.在排序数组中查找元素的第一个和最后一个位置

题目信息:
1.非递减排序数组
2.数组内数值有重复
3.查找target返回起始索引跟结束索引
3.不存在返回-1,-1
解题思路:
1.遍历数组,查找到之后存储起始索引
2.数值发生变化后存储结束索引-1
3.返回

class Solution {

public:

    vector<int> searchRange(vector<int>& nums, int target) {

        vector<int> result = {-1,-1};

        if(nums.size()==0) return result;

        if(nums.size()==1&& nums[0] == target) return {0,0};

        if(nums.size()==1) return {-1,-1};

        int left = 0;

        int right = 0;

        for(int i = 0; i <nums.size()-1;i++){

            if(nums[i] == target){

                left = i;

                break;

            }else{

                left = -1;

        }}

        for(int j = nums.size()-1; j>0; j--){

            if(nums[j] != target){

                right = -1;

                break;

            }else {right = j;

        }}

        return {left,right};

    }

};

提交没通过问题不知道出在哪里。。

二分法确定左右边界:

 while(left<=right){

            int middle = left+((right-left)/2);

            if(nums[middle]>target){

                right = middle -1;

            }else {

                left = middle +1;//因为middle最后是查找的值,middle+1就是rightBorder

                rightBorder =left;

            }

 while(left<=right){

            int middle = left+((right-left)/2);

            if(nums[middle]>=target){//用>= 当nums[middle] == target的时候确定左边界

                right = middle-1;//因为middle最后是查找的值,middle-1就是leftBorder

                leftBorder = right;

            }else{

                left = middle +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题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值