LeetCode每日一题--按既定顺序创建目标数组

leetCode算法系列

Posted by maybelence on 2021-04-14

前言

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

题目描述

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

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

请你返回目标数组。

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

示例 1:

1
2
3
4
5
6
7
8
9
输入: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:

1
2
3
4
5
6
7
8
9
输入: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:

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

提示

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

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

解题思路

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 ,但是殊途同归,也是对每个元素做插入操作。代码也贴出来看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
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

插入排序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
}

总结

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


Copyright by @maybelence.

...

...

00:00
00:00