数组
参考知识点:
# 1. 华为:非递减数组归并
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3]
和 [2,5,6]
。
合并结果是 [1,2,2,3,5,6]
,其中斜体加粗标注的为 nums1
中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1]
和 []
。
合并结果是 [1]
。
思路:
参考力扣第 88 题:合并两个有序数组 (opens new window)。
合并数组后排序,时间复杂度 O(nlogn)
,空间复杂度 O(logn)
。
var merge = function (nums1, m, nums2, n) {
for (let i = 0; i < n; i++) {
nums1[m + i] = nums2[i];
}
nums1.sort((a, b) => a - b);
};
2
3
4
5
6
正序归并,使用一个新数组存放归并值,归并完后再覆盖给 nums1
。时间复杂度 O(n)
,空间复杂度 O(n)
。
var merge = function (nums1, m, nums2, n) {
let i = 0, j = 0, k = 0;
const nums = [];
while (i < m && j < n) {
if (nums1[i] < nums2[j]) {
nums[k++] = nums1[i++];
} else {
nums[k++] = nums2[j++];
}
}
while (i < m) {
nums[k++] = nums1[i++];
}
while (j < n) {
nums[k++] = nums2[j++];
}
nums1.forEach((_, i) => nums1[i] = nums[i]);
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
逆序归并,无论当前数从 nums1
取还是 nums2
取,nums1
留给 nums2
的空位始终与 nums2
待合并的元素数目相等。时间复杂度 O(n)
,空间复杂度 O(1)
。
var merge = function (nums1, m, nums2, n) {
let i = m - 1, j = n - 1, k = m + n - 1;
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j]) {
nums1[k--] = nums1[i--];
} else {
nums1[k--] = nums2[j--];
}
}
while (j >= 0) {
nums1[k--] = nums2[j--];
}
};
2
3
4
5
6
7
8
9
10
11
12
13
# 2. 携程:杨辉三角
给定一个正整数 n
,打印出杨辉三角的前 n
行。
一行中的每个数按空格分隔。
示例:
输入:n = 5
输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
2
3
4
5
思路:
参考力扣第 118 题:杨辉三角 (opens new window)。
迭代,每一行初始化为 [1]
,然后拿上一行的值遍历,最后再补充上一个 1
。
每一次迭代结束,将当前行的值赋给上一行,直至 n
行。
function yanghui(n) {
let i = 0;
let row = [1];
while (i < n) {
if (i > 0) {
let temp = [1];
for (let j = 1; j < row.length; j++) {
temp.push(row[j - 1] + row[j]);
}
temp.push(1);
row = temp;
}
console.log(row.join(' '));
i++;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16