算法刷题2-数组章节

本文介绍了如何运用快慢指针和区域划分策略解决编程问题,包括将0移动到数组末尾、颜色分类、删除有序数组重复项和合并两个有序数组,强调了原地操作和空间复杂度优化。
摘要由CSDN通过智能技术生成

2 数组

2.0 数组题目总结

  1. 双指针
    • 一个遍历,一个指向更新位置
  2. 覆盖操作
    • 如果可以不用在乎某些值,可以直接覆盖,而不是交换。
  3. 区域指针
    • 对问题进行区域划分,使用不同指针指向区域的更新位置。
  4. 总结声明:
    • 总结起来,其实就是区域指针+遍历指针,能解决绝大多数数组题目。
    • 涉及到原地操作的,就是要直接覆盖。

2.1 移动0(LC-283

  1. 问题描述:给定一个数目nums,编写一个函数将所有0移动到数组末尾,同时保持非0元素的相对位置。(原地操作)
  2. 解题思路:双指针
    • 遍历指针遍历数组,位置指针指向更新位置。(覆盖操作)
    • 初始化时,快慢指针都指向0位置。
    • 遍历指针遍历数组,当遍历指针指向的数不为0时,和位置指针互换,并让遍历指针指向下一个位置。
      • 如果不含0,那么两个指针同时会超过数组长度。
      • 如果有0,那么让位置指针指向的位置及以后都赋值为0。
  3. 时间复杂度O(n),空间复杂度O(1)

2.2 颜色分类(LC-75

  1. 问题描述:原地操作数组元素的三种颜色(红、白、蓝),使得数组中相同颜色的相邻,而且保证红、白、蓝的顺序。
  2. 解题思路:三指针:三个区域的划分使用:两个区域指针(left和right)+遍历指针(index)
    • 移动index指针遍历,left初始指向最左边(它左边都是红色),right初始指向最右边(它右边都是蓝色)
    • index遍历值:为红色则和left所指交换,为蓝色则和right所指进行交换,非两边则不动。
  3. 伪代码:
    • index = left = 0;right = nums.length-1;
    • while:index小于right时
      • if:nums[index]等于0
        • swap(nums[index],nums[left])
        • index++
        • right++
      • else if2:nums[index]等于1
        • index++
      • else2 if3:nums[index]等于2
        • swap(nums[index],nums[right])
        • right–
  4. 时间复杂度O(n),空间复杂度O(1)
  5. 衍生问题
    • 对于红色来说,因为遍历的起始位置是从红色那头开始,所以无需再判断交换后的值。
    • 对于蓝色来说,换过来的值并没有进行检查,所以要停留一轮检查一下。

2.3 删除有序数组中的重复项(LC-26

  1. 问题描述:对升序的数组原地删除重复的元素,使得每个元素只出现一次,放回删除后数组的新长度,元素的相对顺序保持一致。
  2. 解题思路:区域指针+遍历指针(覆盖操作)
    • 快指针遍历数组,慢指针指向更新位置。
  3. 伪代码:
    • end=0;cur=1;
    • while:cur小于nums.length
      • if:nums[end]==nums[cur]
        • cur++
      • else:
        • nums[++end] = nums[cur]
  4. 时间复杂度O(n),空间复杂度O(1)

2.4 合并两个有序数组(LC-88

  1. 问题描述:对两个有序数组nums1和nums2进行合并,合并在nums1成为一个有序数组。假设nums1为m+n(初始有效元素为m个),nums2为n。
  2. 解题思路:三指针,一个遍历指针,两个位置指针。
    • 从尾部遍历合并
    • end1从nums1的有效尾部遍历,end2从nums2的有效尾部遍历。end指向nums1的真正尾部。
    • 不断比较end1和end2的大小,大的放入end。
    • 最后如果nums2没遍历完,则把nums2剩下的继续放入nums1
  3. 伪代码:
    • end=m+n-1;end1=m-1;end2=n-1
    • while:end1和end2都大于等于0
      • if:nums1[end1]>nums2[end2]
        • nums1[end] = nums1[end1]
        • end–
        • end1–
      • else:
        • nums1[end] = nums2[end2]
        • end–
        • end2–
    • if:end2大于等于0
      • while(end2>=0)
        • nums1[end] = nums2[end2]
        • end–
        • end2–
  4. 时间复杂度O(m+n),空间复杂度O(m+n)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值