Skip to content

Commit

Permalink
feat: 增加 merge sorted array
Browse files Browse the repository at this point in the history
  • Loading branch information
luzhipeng committed Apr 16, 2019
1 parent 808d840 commit 924f0d1
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 53 deletions.
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ leetcode 题解,记录自己的 leecode 解题之路。
- 图论:最短路径、最小生成树
- 动态规划:背包问题、最长子序列

数据结构,主要有如下几种:

- 数组与链表:单 / 双向链表
- 栈与队列
- 哈希表
- 堆:最大堆 / 最小堆
- 树与图:最近公共祖先、并查集
- 字符串:前缀树(字典树) / 后缀树




## 精彩预告

Expand Down Expand Up @@ -129,14 +140,20 @@ TODO

### 计划

[494.target-sum]
- [494.target-sum]

- [609.find-duplicate-file-in-system]

- anki 卡片

## 交流群

[88.merge-sorted-array]
现在还是初级阶段,需要大家的意见和反馈,为了减少沟通成本,我组建了交流群。大家可以扫码进入

[139.word-break]
![qq-group-chat](./assets/qq-group-chat.png)

[416.partition-equal-subset-sum]
(qq 群)

[609.find-duplicate-file-in-system]
![wechat-group-chat](./assets/wechat-group-chat.png)

anki 卡片
(微信群, 由于微信的限制,只可以七天之内才能加入)
Binary file added assets/problems/88.merge-sorted-array-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/problems/88.merge-sorted-array-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/problems/88.merge-sorted-array-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/qq-group-chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/wechat-group-chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
177 changes: 177 additions & 0 deletions problems/88.merge-sorted-array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
## 题目地址

https://leetcode.com/problems/merge-sorted-array/description/

## 题目描述

```
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.
Example:
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
```

## 思路

符合直觉的做法是`将nums2插到num1的末尾, 然后排序`


具体代码:

```js
// 这种解法连m都用不到
// 这显然不是出题人的意思
if (n === 0) return;
let current2 = 0;
for(let i = nums1.length - 1; i >= nums1.length - n ; i--) {
nums1[i] = nums2[current2++];
}
nums1.sort((a, b) => a - b); // 当然你可以自己写排序,这里懒得写了,因为已经偏离了题目本身

```

这道题目其实和基本排序算法中的`merge sort`非常像,但是 merge sort 很多时候,合并的时候我们通常是
新建一个数组,这样就很简单。 但是这道题目要求的是`原地修改`.

这就和 merge sort 的 merge 过程有点不同,我们先来回顾一下 merge sort 的 merge 过程。

merge 的过程`可以`是先比较两个数组的头元素,然后将较小的推到最终的数组中,并将其从原数组中出队列。
循环直到两个数组都为空。

具体代码如下:

```js
// 将nums1 和 nums2 合并
function merge(nums1, nums2) {
let ret = [];
while (nums1.length || nums2.length) {
// 为了方便大家理解,这里代码有点赘余
if (nums1.length === 0) {
ret.push(nums2.shift());
continue;
}

if (nums2.length === 0) {
ret.push(nums1.shift());
continue;
}
const a = nums1[0];
const b = nums2[0];
if (a > b) {
ret.push(nums2.shift());
} else {
ret.push(nums1.shift());
}
}
return ret;
}
```

这里要求原地修改,其实我们能只要从后往前比较,并从后往前插入即可。

我们需要三个指针:

1. current 用于记录当前填补到那个位置了

2. m 用于记录 nums1 数组处理到哪个元素了

3. n 用于记录 nums2 数组处理到哪个元素了

如图所示:

- 灰色代表 num2 数组已经处理过的元素
- 红色代表当前正在进行比较的元素
- 绿色代表已经就位的元素

![88.merge-sorted-array-1](../assets/problems/88.merge-sorted-array-1.png)
![88.merge-sorted-array-2](../assets/problems/88.merge-sorted-array-2.png)
![88.merge-sorted-array-3](../assets/problems/88.merge-sorted-array-3.png)

## 关键点解析

- 从后往前比较,并从后往前插入

## 代码

```js
/*
* @lc app=leetcode id=88 lang=javascript
*
* [88] Merge Sorted Array
*
* https://leetcode.com/problems/merge-sorted-array/description/
*
* algorithms
* Easy (34.95%)
* Total Accepted: 347.5K
* Total Submissions: 984.7K
* Testcase Example: '[1,2,3,0,0,0]\n3\n[2,5,6]\n3'
*
* Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as
* one sorted array.
*
* Note:
*
*
* The number of elements initialized in nums1 and nums2 are m and n
* respectively.
* You may assume that nums1 has enough space (size that is greater or equal to
* m + n) to hold additional elements from nums2.
*
*
* Example:
*
*
* Input:
* nums1 = [1,2,3,0,0,0], m = 3
* nums2 = [2,5,6], n = 3
*
* Output: [1,2,2,3,5,6]
*
*
*/
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function(nums1, m, nums2, n) {
// 设置一个指针,指针初始化指向nums1的末尾
// 然后不断左移指针更新元素
let current = nums1.length - 1;

while (current >= 0) {
// 没必要继续了
if (n === 0) return;

// 为了方便大家理解,这里代码有点赘余
if (m < 0) {
nums1[current--] = nums2[--n];
continue;
}

if (n < 0) {
nums1[current--] = nums1[--m];
continue;
}
// 取大的填充 nums1的末尾
// 然后更新 m 或者 n
if (nums1[m - 1] > nums2[n - 1]) {
nums1[current--] = nums1[--m];
} else {
nums1[current--] = nums2[--n];
}
}
};
```
47 changes: 0 additions & 47 deletions todo/88.merge-sorted-array.js

This file was deleted.

0 comments on commit 924f0d1

Please sign in to comment.