88. 合并兩個(gè)有序數(shù)組:
給你兩個(gè)按 非遞減順序 排列的整數(shù)數(shù)組 nums1
和 nums2
,另有兩個(gè)整數(shù) m
和 n
,分別表示 nums1
和 nums2
中的元素?cái)?shù)目。
請你 合并 nums2
到 nums1
中,使合并后的數(shù)組同樣按 非遞減順序 排列。
注意:最終,合并后數(shù)組不應(yīng)由函數(shù)返回,而是存儲在數(shù)組 nums1
中。為了應(yīng)對這種情況,nums1
的初始長度為 m + n
,其中前 m
個(gè)元素表示應(yīng)合并的元素,后 n
個(gè)元素為 0
,應(yīng)忽略。nums2
的長度為 n
。文章來源:http://www.zghlxwxcb.cn/news/detail-754914.html
樣例 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] 。
合并結(jié)果是 [1,2,2,3,5,6] ,其中斜體加粗標(biāo)注的為 nums1 中的元素。
樣例 2:
輸入:
nums1 = [1], m = 1, nums2 = [], n = 0
輸出:
[1]
解釋:
需要合并 [1] 和 [] 。
合并結(jié)果是 [1] 。
樣例 3:
輸入:
nums1 = [0], m = 0, nums2 = [1], n = 1
輸出:
[1]
解釋:
需要合并的數(shù)組是 [] 和 [1] 。
合并結(jié)果是 [1] 。
注意,因?yàn)?m = 0 ,所以 nums1 中沒有元素。nums1 中僅存的 0 僅僅是為了確保合并結(jié)果可以順利存放到 nums1 中。
提示:
- nums1.length == m + n
- nums2.length == n
- 0 <= m, n <= 200
- 1 <= m + n <= 200
- -109 <= nums1[i], nums2[j] <= 109
分析:
- 面對這道算法題目,二當(dāng)家的再次陷入了沉思。
- 如果直接就把
nums2
放到num1
后面,然后再對合并后的num1
進(jìn)行排序,時(shí)間復(fù)雜度是O((m+n)log(m+n))
,不是很理想,完全沒有使用數(shù)組本身有序這個(gè)便利條件。 - 對排序算法熟悉的話,可以想到歸并排序算法,其中將兩個(gè)有序部分合并到一起正好就是我們要做的,但是這樣需要額外的空間,而且最后還需要把結(jié)果再拷貝回
num1
。 - 稍稍做下優(yōu)化,前面我們之所以要使用額外空間就是因?yàn)樘幚磉^程中會把還沒有處理的
num1
部分覆蓋,我們可以逆向遍歷處理,因?yàn)樽铋_始num1
的后半部分是空的,所以我們就選取較大值放到末尾,依次處理,而且只要將nums2
處理完畢就可以停止了,因?yàn)?num1
的剩余部分已經(jīng)是有序的,這樣不需要額外空間,而且時(shí)間復(fù)雜度僅僅是O(m+n)
,非常不錯(cuò)。
題解:
rust:
impl Solution {
pub fn merge(nums1: &mut Vec<i32>, m: i32, nums2: &mut Vec<i32>, n: i32) {
let (mut l1, mut l2, mut l) = (m - 1, n - 1, m as usize + n as usize - 1);
while l2 >= 0 {
if l1 >= 0 && nums1[l1 as usize] > nums2[l2 as usize] {
nums1[l] = nums1[l1 as usize];
l1 -= 1;
} else {
nums1[l] = nums2[l2 as usize];
l2 -= 1;
}
l -= 1;
}
}
}
go:
func merge(nums1 []int, m int, nums2 []int, n int) {
l1, l2, l := m-1, n-1, m+n-1
for l2 >= 0 {
if l1 >= 0 && nums1[l1] > nums2[l2] {
nums1[l] = nums1[l1]
l1--
} else {
nums1[l] = nums2[l2]
l2--
}
l--
}
}
c++:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int l1 = m - 1;
int l2 = n - 1;
int l = m + n - 1;
while (l2 >= 0) {
nums1[l--] = l1 >= 0 && nums1[l1] > nums2[l2] ? nums1[l1--] : nums2[l2--];
}
}
};
python:
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
l1, l2, l = m - 1, n - 1, m + n - 1
while l2 >= 0:
if l1 >= 0 and nums1[l1] > nums2[l2]:
nums1[l] = nums1[l1]
l1 -= 1
else:
nums1[l] = nums2[l2]
l2 -= 1
l -= 1
java:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int l1 = m - 1;
int l2 = n - 1;
int l = m + n - 1;
while (l2 >= 0) {
nums1[l--] = l1 >= 0 && nums1[l1] > nums2[l2] ? nums1[l1--] : nums2[l2--];
}
}
}
非常感謝你閱讀本文~
歡迎【點(diǎn)贊】【收藏】【評論】三連走一波~
放棄不難,但堅(jiān)持一定很酷~
希望我們大家都能每天進(jìn)步一點(diǎn)點(diǎn)~
本文由 二當(dāng)家的白帽子:https://le-yi.blog.csdn.net/ 博客原創(chuàng)~文章來源地址http://www.zghlxwxcb.cn/news/detail-754914.html
到了這里,關(guān)于算法leetcode|88. 合并兩個(gè)有序數(shù)組(rust重拳出擊)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!