Day01 | 数组理论基础、leetcode704. 二分查找、leetcode27. 移除元素

文章介绍了数组的基础理论,包括其内存特性和操作限制。作者通过二分查找(LeetCode704)和移除元素(LeetCode27)的题目,讨论了编程实现中的关键点,如循环不变量和防止溢出。强调了在解决算法题时理解题意和优化代码的重要性,并提出使用本地IDE可以提高效率。
摘要由CSDN通过智能技术生成

数组理论基础

1. 数组是存放在连续内存空间上的相同类型数据的集合。
2. 数组内存空间的地址是连续的。(因此在删除或者增添元素的时候,就难免要移动其他元素的地址。)
3. 数组的元素不能删除,只能覆盖。
4. C++中二维数组在地址空间上是连续的。

leetcode704. 二分查找

这题是二刷了,一看到题就马上知道思路,但是用代码实现起来还是有些问题在的,所以还得多写代码。在面试笔试的时候也是这样,很多题虽做过但实现起来不顺利,没做过的能想出思路但实现不了,应该还是写代码写少了,继续加油。
总结一下这题的注意点:

  1. 弄清楚哪些才是变量(要操作的数组,指向数组的左右边界指针left和right,中间值的下标mid)。只要改变left和right指针就能改变要操作的数组nums,因此变量只有left,right,mid。
  2. 循环不变量规则。弄清楚哪些是不变量,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
  3. 防止溢出操作:left + ((right - left) >> 1)。位运算>>效率比 /2 效率高。
  4. 开头先排除掉一些特殊情况,提升代码效率。
class Solution {
    public int search(int[] nums, int target) {
        int len = nums.length;
        // 当 target 小于 nums[0] 或大于 nums[len - 1] 时,直接返回-1,避免进入while循环进行多次计算
        if (target < nums[0] || target > nums[len - 1]) {
            return -1;
        }
        // 左闭右闭区间
        int left = 0;
        int right = len - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);     // 防止溢出 等同于(left + right)/2
            if (target > nums[mid]) {
                left = mid + 1;
            } else if (target < nums[mid]) {
                right = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

拓展题目(二刷再做,现在没时间)
leetcode35. 搜索插入位置
leetcode34. 在排序数组中查找元素的第一个和最后一个位置

leetcode27. 移除元素

这题也是二刷,虽然在不看提示的情况下最后也写出来提交AC了,但是前几次提交都通过不了,主要是没看清题目的具体意思。还有这里建议用本地IDE来做算法题(建了个随想录的文件夹,不同数据结构的题目分别放好来),一是方便debug,二是效率高(写代码有提示、运行程序比浏览器快、方便写输入测试样例等),下面除了有我力扣上的代码,也有在IDE上的代码展示。
总结一下这题的注意点:

  1. 弄清楚题目的意思(返回的是新数组的长度以及新数组)。在第一遍提交时没AC
  2. 双指针的起始点;
  3. 根据题意,if() 的判断条件设置为查找值不等于val会更方便。因为目标是把等于val的值都移到数组尾部,不等于val的元素都放在数组头部,所以当查找值不等于val时才交换slow和fast指向的元素,这样就能达成目标
  4. 我的代码和随想录的法一有点出入。随想录上的是直接覆盖掉等于val的元素了,而我的是把等于val值的元素都移到了数组尾部。
  5. 法二:相向双指针法。等有空再写

在力扣上写题:

class Solution {
	// 法一:快慢双指针
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        // 定义快慢指针
        int slow = 0;
        int fast = 0;
        // 遇到不等于val值的元素,则进行交换,并使慢指针右移一位;快指针在每一次循环都要右移一位;
        while (fast < len) {
            if (nums[fast] != val) {
                int tmp = nums[fast];
                nums[fast] = nums[slow];
                nums[slow] = tmp;
                slow++;
            }
            fast++;
        }
        int ans = slow;
        return ans;
    }
}

在本地IDE上写题:

public class leetcode27 {
    public static int removeElement(int[] nums, int val) {
        int len = nums.length;
        // 定义快慢指针
        int slow = 0;
        int fast = 0;
        // 遇到不等于val值的元素,则进行交换,并使慢指针右移一位;快指针在每一次循环都要右移一位;
        while (fast < len) {
            if (nums[fast] != val) {
                int tmp = nums[fast];
                nums[fast] = nums[slow];
                nums[slow] = tmp;
                slow++;
            }
            fast++;
        }
        int ans = slow;
        return ans;
    }

    // 在main方法里调用
    public static void main(String[] args) {
        int[] nums = {3,2,2,3};
        //int[] nums = {0,1,2,2,3,0,4,2};
        //int[] nums = {3,3,3,3};
        int val = 3;
        // 调用函数
        int ans = removeElement(nums, val);
        System.out.println(ans);
    }
}

拓展题目(二刷再做,现在没时间)
leetcode26. 删除排序数组中的重复项
leetcode283. 移动零
leetcode844. 比较含退格的字符串
leetcode977. 有序数组的平方

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值