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

数组理论基础

文档讲解:代码随想录

视频讲解:数组理论B站

目标:了解一下数组基础,以及数组的内存空间地址,数组也没那么简单。

状态:基本了解,主要细节,数组是存放在连续内存空间上的相同类型数据的集合,是通过下表索引进行访问,下标都是从0开始,内存空间的地址是连续的。

java的数组排列方式不太一样,因为java没有指针,所以寻址操作是交给虚拟机的,示意图如下:

704 . 二分查找

文档讲解:代码随想录

视频讲解:手把手带你撕出正确的二分法

状态:有思想,写代码时候遇到java语法问题(太久没写Java了)

目标:先把 704写熟练,要熟悉 根据 左闭右开,左闭右闭 两种区间规则 写出来的二分法

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

其中一个语法细节{ (right - left) >> 1 },>>相当于除以2然后取整。参考连接:Java 中的位移运算符 >> , << , >>>

27. 移除元素

 题目链接:27. 移除元素

文档讲解:代码随想录

视频讲解:LeetCode:27. 移除元素

状态:第一遍看题目有点懵逼不知道要干嘛,然后看解析知道了思想,了解了两种写法,分别是双循环暴力破解,双指针。然后就是进阶的左右双指针。

目标:暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握

//暴力破解法
class Solution {
    public int removeElement(int[] nums, int val) {
        int size = nums.length;
        for (int i = 0; i < size; i++) {
            if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
                for (int j = i + 1; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
                size--; // 此时数组的大小-1
            }
        }
        return size;
    }
}
//双指针
class Solution {
    public int removeElement(int[] nums, int val) {
        int fast,slow = 0;
        // System.out.println("slow:"+slow);
        for(fast = 0;fast<nums.length;fast++){
            if(nums[fast]!=val){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}
//左右指针比较巧妙的解法
class Solution {
    public int removeElement(int[] nums, int val) {
        int j = nums.length - 1;
        for (int i = 0; i <= j; i++) {
            if (nums[i] == val) {
                swap(nums, i--, j--);
            }
        }
        return j + 1;
    }
    void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

执行过程:

对于这个例子 [0,1,2,2,3,0,4,2] 和 val = 2:

初始化 j = nums.length - 1 = 7,i = 0。

进入循环,i = 0,j = 7,nums[i] = 0,不等于 val,所以 i 增加 1。

  1. i = 1,j = 7,nums[i] = 1,不等于 val,所以 i 增加 1。
  2. i = 2,j = 7,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,2,2,3,0,4,2],i = 1,j = 6。
  3. i = 1,j = 6,因为 i 减少了 1,所以我们回到 nums[1],它等于 1,不等于 val,所以 i 增加 1。
  4. i = 2,j = 6,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,4,2,3,0,2,2],i = 1,j = 5。
  5. i = 1,j = 5,因为 i 减少了 1,所以我们回到 nums[1],它等于 1,不等于 val,所以 i 增加 1。
  6. i = 2,j = 5,nums[i] = 4,不等于 val,所以 i 增加 1。
  7. i = 3,j = 5,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,4,0,3,2,2,2],i = 2,j = 4。
  8. i = 2,j = 4,因为 i 减少了 1,所以我们回到 nums[2],它等于 4,不等于 val,所以 i 增加 1。
  9. i = 3,j = 4,nums[i] = 0,不等于 val,所以 i 增加 1。
  10. i = 4,j = 4,nums[i] = 3,不等于 val,所以 i 增加 1。
  11. 现在 i = 5,j = 4,i > j,所以退出循环。
  12. 返回 j + 1 = 5,这是新的数组长度。

所以,最后的结果是数组变为 [0,1,4,0,3,2,2,2],新的数组长度为 5。注意,数组的后三个元素是无效的,因为它们已经被移除

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练营主要涵盖了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、付费专栏及课程。

余额充值