双指针合并有序数组:求解《88. 合并两个有序数组》和《面试题 10.01. 合并排序的数组》

2022-05-01 14:59:07

双指针合并有序数组,注意数组越界不同语言的处理方式。求解《88. 合并两个有序数组》和《面试题 10.01. 合并排序的数组》

有序数组的合并过程模拟示意图

合并有序数组

例题

88. 合并两个有序数组

面试题 10.01. 合并排序的数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

答案

双指针

var merge = function(nums1, m, nums2, n) {
  let p1 = m - 1, p2 = n - 1, i = m + n - 1
  while (p1 > -1 || p2 > -1) {
    nums1[i--] = p2 < 0 || nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--]
  }
};
func merge(nums1 []int, m int, nums2 []int, n int)  {
  p1, p2, i := m - 1, n - 1, m + n - 1
  for p1 > -1 || p2 > -1 {
    if p2 < 0 || p1 >= 0 && nums1[p1] > nums2[p2] {
      nums1[i] = nums1[p1]
      p1--
    } else {
      nums1[i] = nums2[p2]
      p2--
    }
    i--
  }
}
class Solution {
  function merge(&$A, $m, $B, $n) {
    $p1 = $m - 1;
    $p2 = $n - 1;
    $i = $m + $n - 1;
    while ($p1 > -1 || $p2 > -1) {
      $A[$i--] = $p2 < 0 || $A[$p1] > $B[$p2] ? $A[$p1--] : $B[$p2--]; 
    }
  }
}

5 种方法交换变量,用绝对值和求模标记,用位图、掩码、哈希集合、哈希映射、正则、排序和暴力法:求解《442. 数组中重复的数据》
利用 5 种方法交换变量,用绝对值和求模标记,用位图、掩码、哈希集合、哈希映射、正则、排序和暴力法求解《442. 数组中重复的数据》
二分查找(对数运算 + 前缀和),滑动窗口:求解《713. 乘积小于 K 的子数组》
根据对数运算性质将相乘转为求和问题,用前缀和优化。二分查找,滑动窗口,求解《713. 乘积小于 K 的子数组》
递归和双指针迭代:求解《21. 合并两个有序链表》和《剑指 Offer 25. 合并两个排序的链表》
递归和双指针迭代,求解《21. 合并两个有序链表》和《剑指 Offer 25. 合并两个排序的链表》