[LeetCode1389题 - 按既定顺序创建目标数组] | 刷题打卡

311 阅读2分钟

掘金团队号上线,助你 Offer 临门! 点击 查看详情

前言

今天刷到的这个题目,从难度而言非常简单,甚至可以瞬秒,但是延伸一下很容易想到基础排序里面非常常见的一种--插入排序 。所以借着今天的题目,正好额外复习一下插入排序。

题目描述

给你两个整数数组 numsindex。你需要按照以下规则创建目标数组:

  • 目标数组 target 最初为空。
  • 按从左到右的顺序依次读取 nums[i]index[i],在 target 数组中的下标 index[i] 处插入值 nums[i]
  • 重复上一步,直到在 numsindex 中都没有要读取的元素。

请你返回目标数组。

题目保证数字插入位置总是存在。

 

示例 1:

输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums       index     target
0            0        [0]
1            1        [0,1]
2            2        [0,1,2]
3            2        [0,1,3,2]
4            1        [0,4,1,3,2]

示例 2:

输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums       index     target
1            0        [1]
2            1        [1,2]
3            2        [1,2,3]
4            3        [1,2,3,4]
0            0        [0,1,2,3,4]

示例 3:

输入:nums = [1], index = [0]
输出:[1]

提示

  • 1 <= nums.length, index.length <= 100
  • nums.length == index.length
  • 0 <= nums[i] <= 100
  • 0 <= index[i] <= i

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/cr… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

这个题目主要还是把题目意思理解清楚。根据示例,当新数组对应 index[i] 下标已经存在元素时,新的 num[i] 会插入到这个坐标之中。原本填充在 index[i] 元素会依次向后移动一位。理解了这个之后。就会发现,相当于对每个元素,他都是执行了一个插入操作。所以代码也就能很容易写出来:

class Solution {
    int[] array;

    public int[] createTargetArray(int[] nums, int[] index) {
        array = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            generateNewArray(nums[i], index[i]);
        }
        return array;
    }

    //插入数据
    private void generateNewArray(int num, int index) {
        for (int i = array.length - 1; i > index; i--) {
            array[i] = array[i - 1];
        }
        array[index] = num;
    }
}

LeetCode 官网题解引了个 List ,但是殊途同归,也是对每个元素做插入操作。代码也贴出来看一下:

class Solution {
    public int[] createTargetArray(int[] nums, int[] index) {
        List<Integer> targetList = new ArrayList<>();
        for(int i =0;i<nums.length;i++){
            targetList.add(index[i],nums[i]);
        }
        int[] target = new int[nums.length];
        for(int i = 0;i<nums.length;i++){
            target[i] = targetList.get(i);
        }
        return target;
    }
}

题目到这里结束了。但是这个插入过程,很像我们做插排的时候。我们做插排的时候,默认第一个元素是最小的元素,从 i=1 开始遍历,如 (a) 从 2 开始遍历,然后寻找插入位置。如果在左边找到了插入位置,那么左边插入之后就是有序的,如果左边没有插入位置,说明左边所有元素包括当前元素,都是有序的,如图 (d) 。

image.png

插入排序代码

class Solution {
    
    public int[] insertSort(int[] arr) {
        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {
            // 记录要插入的数据
            int tmp = arr[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1]; 
                j--;
            }
            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }
        }
        return arr;
    }
}

总结

今天题目不难,但是多复习了一个基础排序,感觉也是有所收获。在每次刷题的时候,多去思考之前是否遇到相似场景。不至于遗忘之前的知识。顺便推荐一下我最近两天的文章,也是很有共性的两篇动态规划: