力扣算法之数组

本文介绍了数组的基本概念,包括数组的内存布局和下标特性,并探讨了数组在不同编程语言中的差异。文章重点讲解了在算法中常用的数组操作方法,如二分查找、双指针、滑动窗口等,并通过力扣(LeetCode)的典型题目实例,如移除元素、有序数组的平方、最短子数组和螺旋矩阵等,深入阐述了这些方法的实现和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组

数组基本概念

  • 数组是存放在连续内存空间上相同类型数据的集合
    • 数组下标都是从0开始的
    • 数组内存空间的地址是连续的
  • 数组的元素是不能删的,只能覆盖
  • 二维数组在内存的空间地址是连续的么?
    • 不一定,比如在c++中是,但是在java中不是
  • 数组方便查找,不方便插入和删除,这和它存储的空间连续有关

主要方法

  • 二分法
  • 双指针(快慢指针)
  • 滑动窗口

示例

二分查找

题目链接:[704.二分查找](Loading Question… - 力扣(LeetCode) (leetcode-cn.com))

image.png

解答:二分法

var search = function(nums, target) {
    let left = 0, right = nums.length - 1;
    while(left <= right){
        // let mid = left + Math.floor((right - left) / 2); 
        let mid = left + ((right - left) >> 1);
        if(nums[mid] < target){
            left = mid + 1;
        } else if(nums[mid] > target){
            right = mid - 1;
        } else {
            return mid;
        }

    }
    return -1;
};

说明:

  • 注意根据while里面的条件判断区间的开闭情况,right = nums.length - 1while(left <= right)则为左闭右闭区间,所以left = mid + 1; right = mid - 1

  • right = nums.lengthwhile(left < right)则为左闭右开区间,所以left = mid + 1; right = mid

  • 注意let mid = left + ((right - left) >> 1);其中的((right - left) >> 1)是需要用括号括起来的,不然的话会出错,因为优先级的问题。

移除元素

题目链接:[27.移除元素](Loading Question… - 力扣(LeetCode) (leetcode-cn.com))

image.png

解答:快慢指针

var removeElement = function(nums, val) {
   let left = 0;
   for(let i = 0; i < nums.length; i++){
       if(nums[i] !== val){
           nums[left++] = nums[i];
       }
   }
   return left;
};
有序数组的平方

题目链接:[977.有序数组的平方](977. 有序数组的平方 - 力扣(LeetCode) (leetcode-cn.com))

image.png

解答:双指针

var sortedSquares = function(nums) {
    let left = 0, right = nums.length - 1, k = nums.length - 1;
    let res = new Array(nums.length).fill(0);
    while(left <= right){
        let l = nums[left] * nums[left];
        let r = nums[right] * nums[right];
        if(l < r){
            res[k--] = r;
            right--;
        } else {
            res[k--] = l;
            left++;
        }
    }
    return res;
};
长度最小的子数组

题目链接:[209.长度最小的子数组](209. 长度最小的子数组 - 力扣(LeetCode) (leetcode-cn.com))

image.png

解答:滑动窗口

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置

var minSubArrayLen = function(target, nums) {
    let left = 0, len = Infinity, sum = 0, subLen = 0;
    for(let right = 0; right < nums.length; right++){
        sum += nums[right];
        while(sum >= target){
            subLen = right - left + 1;
            len = Math.min(subLen, len);
            sum -= nums[left++];
        }
    }
    return len === Infinity ? 0 : len;
};
螺旋矩阵II

题目链接:[59.螺旋矩阵II](59. 螺旋矩阵 II - 力扣(LeetCode) (leetcode-cn.com))

image.png

解答:模拟

var generateMatrix = function(n) {
    let startX = startY = 0;  // 起始位置
    let loop = Math.floor(n / 2);  // 旋转圈数
    let mid = Math.floor(n / 2);  // 中间位置
    let offset = 1; // 每一行填充元素的个数
    let count = 1; // 每一行填充元素的值
    let res = new Array(n).fill(0).map(() => new Array(n).fill(0));
    while(loop--){
        let row = startX, col = startY;
        // n - offset表示剩余长度,startY + 剩余长度正好是这一圈循环的边界
        for(;col < startY - offset + n; col++){
            res[row][col] = count++;
        }
        for(;row < startX - offset + n; row++){
            res[row][col] = count++;
        }
        for(;col > startX; col--){
            res[row][col] = count++;
        }
        for(;row > startX; row--){
            res[row][col] = count++;
        }
        startX++;
        startY++;
        offset += 2; // 每走完一圈都会加2
    }
    // 如果是奇数时需要另外处理
    if(n % 2 === 1){
        res[mid][mid] = count;
    }
    return res;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力不熬夜的小喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值