题目:
给你两个按
非递减顺序
排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。
为了应对这种情况,nums1 的初始长度为 m + n
,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
题解:
自己刚开始看到这题,第一反应是,两个数组都是有序的,我只需要将两个数组都正着遍历一遍就可以排好了,很快就感觉不对劲,按照前面的思路可能会覆盖 nums1 中的部分数据,这种方法不行,然后就心生一计,用更多的空间就可以解决,然后就出现了下面的代码
func merge(nums1 []int, m int, nums2 []int, n int) {
mTempSlice := make([]int, m+n)
mIdx := 0 // 指向 mTempSlice 的idx
mCurIdx := 0 // 指向 nums1 的idx
for i := 0; i < n; i++ {
mNum2 := nums2[i]
for mCurIdx < m {
mNum1 := nums1[mCurIdx]
if mNum2 >= mNum1 {
// 插入1
mTempSlice[mIdx] = mNum1
mIdx++
mCurIdx++
} else {
// 插入2
mTempSlice[mIdx] = mNum2
mIdx++
break
}
}
// 这里是为了当 nums1 中的数据都插入完毕了,插入剩余 nums2 中的数据
if mCurIdx >= m {
// 这里可以直接用 copy 将剩余的 nums2 中的数据拷贝到 nums1 中
mTempSlice[mIdx] = mNum2
mIdx++
}
}
// 这里是防止 nums2 中的数据插入完毕了,nums1 中还有数据没有插入完毕
for mCurIdx < m {
mTempSlice[mIdx] = nums1[mCurIdx]
mIdx++
mCurIdx++
}
// 这里是出现过 n = 0 的情况,其实这里可以直接在方法最开始的地方加上,然后直接跳出程序
if n > 0 {
copy(nums1, mTempSlice)
}
// 上面的代码都是写了测试,改过几个地方,慢慢加代码的所有版本合起来的
// 所以会出现有些地方代码用不恰当,放在这里只是为了后期回想当时的思路
}
看了一眼官方的结题,发现我上面这搞得有点复杂了,官方简单的直接将 nums2 的数据拷贝到 nums1 的后半部分中,然后用官方的库直接排序,我看到后呆了,还带这样玩的
func merge(nums1 []int, m int, nums2 []int, _ int) {
copy(nums1[m:], nums2)
sort.Ints(nums1)
}
然后继续看,下面发现了一个倒着排的,这样就不会出现 nums1 的数据被覆盖的情况了,然后紧接着就自己撸了一下,这脑子还是得多转转
func merge(nums1 []int, m int, nums2 []int, n int) {
mIdx1, mIdx2 := m-1, n-1
mIdx := m + n - 1
for mIdx >= 0 {
if mIdx1 < 0 {
copy(nums1[:mIdx+1], nums2[:mIdx2+1])
break
}
if mIdx2 < 0 {
break
}
if nums1[mIdx1] >= nums2[mIdx2] {
nums1[mIdx] = nums1[mIdx1]
mIdx--
mIdx1--
} else {
nums1[mIdx] = nums2[mIdx2]
mIdx--
mIdx2--
}
}
}
题目来源:力扣题库
一点点笔记,以便以后翻阅。