算法札记——4.25

今日在刷算法题的过程中看到了一道比较有意思的题目。故此分享,亦作笔记之用。

那就赶快来看看该题:88. 合并两个有序数组 - 力扣(LeetCode)

按照题目要求是是让我们合并nums1和nums2俩个有序数组到nums1中。首先可以想到的最为简单粗暴的解法便是将nums2的所有数据都放到nums1中的无效位置(下标m, m + n - 1的区间),再使用排序算法对nums1进行排序。

固然上述方法是可以解决,但不够优雅,并且题目中存在一个进阶要求------时间复杂度O(m + n)。而上一个方法的时间复杂度至少也是O(NlogN)。此时,通过前面提到的排序与标题中的归并,我们不难想到一个可以满足该要求的方法:即创建一个拷贝数组tmp,使用归并的思想将nums1与nums2两个有序数组放到tmp,最后再将tmp拷贝回nums1中即可。

上述方法确实可行,但这样也无法称之为优雅。此时我们会想着如果不使用这个拷贝数组tmp,让空间复杂度降到O(1)便能进行合并就好了。接下来便是这道题的巧妙之处:

我们可以发现nums1的数组长度是m + n,无效数据全部存储再前m位置,后面存在n个无效数据的长度。我们是否可以将合并的方式反过来,即从后往前进行归并,将两数组中最大的数据先放到末尾位置,即:

通过逆序的方法进行合共两数组,从两数组有效数据的末尾位置开始从后往前进行合并,从末尾位置开始,每次合并从后往前将比较大的数放到nums1的数组中。

此时可能会考虑一个问题,nums2中的数据会不会影响到nums1中的有效数据?答案是否定的。

这是由于nums1中无效数据的长度为n,即使nums1所有的数据均小于nums2,也仅到下标m的位置,若存在大于nums2的数据,会从后往前缩小nums1的有效数据长度,最终也会是刚好在有效数据的下个位置停下,所以合并过程中是肯定不会影响到nums1中的有效数据的。

以下是题解代码:

cpp 复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int 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--];
            --k;
        }
        while (j >= 0)
            nums1[k--] = nums2[j--];
    }
};
相关推荐
Logic1015 天前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
Logic1016 天前
C语言/数据结构位运算题解:异或XOR找出优秀项目组中的“独特编号“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic1016 天前
C语言/数据结构字符串题解:最短循环节——找出能重复构成原串的最短基础子串
c语言·数据结构·字符串·枚举·时间复杂度·算法题·kmp优化
Logic1018 天前
C语言/数据结构位运算题解:异或XOR找出英雄队伍中的“独特战斗力“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic1018 天前
C语言/数据结构动态规划题解:爬楼梯(含坏台阶)——避开障碍物的路径计数
c语言·数据结构·动态规划·时间复杂度·空间复杂度·算法题·爬楼梯
Logic1019 天前
C语言/数据结构排序题解:三个数的最大乘积——排序后比较两种候选情况
c语言·数据结构·数组·排序·时间复杂度·算法题·负数处理
Logic10110 天前
C语言/数据结构贪心算法题解:字符串趋同——逐位统计最高频率求最小修改代价
c语言·数据结构·贪心算法·字符串·时间复杂度·频率统计·算法题
Logic10113 天前
C语言/数据结构字符串题解:按字符类型重排(数字→字母→符号)——三趟扫描稳定分区
c语言·数据结构·字符串·时间复杂度·计数排序·算法题·ascii
Logic10113 天前
C语言/数据结构位运算题解:异或XOR找出学习计划中的“独特学习时间“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic10113 天前
C语言/数据结构位运算题解:异或XOR找出弹子游戏机中数量为奇数的数字——只出现奇数次
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质