代码随想录算法训练营第一天(LeetCode704二分查找、27移除元素)

704:二分查找

思想:通过不断缩小区间范围来搜索target

注意事项:注意区间范围

        如果是[left,right]区间的话,需要判断left和right下标对应的值是否满足条件,因此初始的时候left=0,right=len-1,每次二分的时候找left和right的中间下标index,如果target比nums[index]小,right-1,如果比nums[index]大,left+1,如果等于的话说明找到了下标,直接return就行。左右都是闭区间的话,left==right是有意义的,所以得是while (left <= right)。例如数组只有一个元素5,target=5,那么只有while (left <= right)时才能进入循环。

        如果是[left,right)的话,初始条件right=len,而不是len-1,右边的开区间,因此每次更新的时候right不需要减1,left==right也是没有意义的,因此直接是while (left < right)

具体实现:i表示左边,j表示右边,index的中点,res是返回值

代码:

1、左闭右闭

class Solution {
    public int search(int[] nums, int target) {
        int len = nums.length;
        int i = 0, j = len-1, res = -1;
        
        while(i<=j){
            int index = (j+i)/2;
            if(target<nums[index]){
                j = index - 1;
            }else if(target>nums[index]){
                i = index + 1;
            }else{
                res = index;
                break;
            }
        }
        return res;
    }
}

2、左闭右开

class Solution {
    public int search(int[] nums, int target) {
        int len = nums.length;
        int i = 0, j = len, res = -1;
        
        while(i<j){
            int index = (i+j)/2;
            if(target<nums[index]){
                j = index;
            }else if(target>nums[index]){
                i = index + 1;
            }else{
                res = index;
                break;
            }
        }
        return res;
    }
}

35:搜索插入位置

思想:利用二分法的思想使得时间复杂度为O(logn)

关键:找到的话直接返回数组下标,如果没找到的话“返回它将会被按顺序插入的位置”。对于左闭右闭的情况,循环结束的条件要么是找到了下标,如果没找到下标的话就是left=right+1,left所处的小标就应该是target按顺序应该插入的位置,所以应该return left。对于左闭右开的情况下,如果没找到下标,要么left=right+1或者left=right,所以还是返回left位置。

代码:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int len = nums.length;
        int left = 0, right = len - 1;
        while(left<=right){
            int index = (left + right)/2;
            if(target<nums[index]){
                right = index - 1;
            }else if(target>nums[index]){
                left = index + 1;
            }else{
                return index;
            }
        }

        return left;
    }
}

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

方法:在二分法查找的基础上,先找到元素所在的位置,然后再通过左右滑动查找左边界和右边界。

代码:

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        int left = 0, right = len - 1;
        int[] res = {-1,-1};
        while(left<=right){
            int index = (left + right)/2;
            if(target<nums[index]){
                right = index - 1;
            }else if(target>nums[index]){
                left = index + 1;
            }else{
                for(int i =index;i>=left;i--){
                    if(nums[i]!=target){
                        res[0] = i+1;
                        break;
                    }else{
                        res[0] = left;
                    }
                }
                for(int j=index;j<=right;j++){
                    if(nums[j]!=target){
                        res[1] = j-1;
                        break;
                    }else{
                        res[1] = right;
                    }
                }
                break;
            }
        }
        return res;
    }
}

27:移除元素

思想:双指针法:通过快指针和慢指针把不等于val的元素往前靠。筛选掉val,val的位置空出来,就可以插入后面的值。

代码:

class Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        int slowIndex=0;
        
        for(int fastIndex=0;fastIndex<len;fastIndex++){
            if(val!=nums[fastIndex]){
                nums[slowIndex++]=nums[fastIndex];
            }
        }
        return slowIndex;
    }
}

今日感想:

算法思路理解和代码实现还是有一定区别的,再理清算法思路的基础上,代码实现还需要考虑更多的细节。
 

第二十二天的算法训练营主要涵盖了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、付费专栏及课程。

余额充值