大家好今天给大家分享下一道 LeetCode 中等难度 的题目[旋转数组]
这里主要是分享思路和注释,供大家更好的理解题目解法,代码部分是参考LeetCode 转写成javascript 代码,
题目
给定一个数组,将数组中的元素向右移动
k个位置,其中k是非负数。
示例 1: 输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4] 示例 2: 输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右旋转 1 步: [99,-1,-100,3] 向右旋转 2 步: [3,99,-1,-100]
分析
1.移动k位置,k>=0
2.目标:最后k个元素放在前面去
解法
1.双数组
2.reverse
3.pop+unshift
解法一:双数组
思路
1.拿2个数组,一个存放旋转数组的前缀元素,一个存放后缀元素
2.更新原数组
*/
var rotate = function (nums, k) {
const preArr = [],
sufArr = [];
const len = nums.length;
// 排序K>len的情况,取余数
k = k % len;
// preArr 存放前缀元素,sufArr存放后缀元素
for (let i = 0; i < nums.length; i++) {
if (i < len - k) preArr[i] = nums[i];
else sufArr[i] = nums[i];
}
// 更新原数组
for (let i = 0; i < nums.length; i++) {
if (i < k) nums[i] = sufArr[i + len - k];
else nums[i] = preArr[i - k];
}
};
/* 复杂度
时间 O(n)
空间 O(n)
*/
解法二:双指针
思路
1.利用双指针翻转数组
2.把整个数组都翻转
3.移动k位置,翻转k之前的数组
4.翻转k之后的数组
*/
var rotate = function (nums, k) {
const len = nums.length;
// 取余数,防止过界
k = k % len;
// 利用双指针进行翻转
function reverse(arr, start, end) {
for (let left = start, right = end; left < right; ) {
// 交换元素
const temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
//翻转整个数组
reverse(nums, 0, len - 1);
// 翻转k之前的数组
reverse(nums, 0, k - 1);
// 翻转k之后的数组
reverse(nums, k, len - 1);
};
/* 复杂度
时间 O(n)
空间 O(1)
*/
解法三:unshift+pop(超时只是作为参考)
思路
1.取出k个元素
2.放在之后
*/
var rotate = function (nums, k) {
for (let i = 0; i < k; i++) {
const item = nums.pop();
nums.unshift(item);
}
};
/* 复杂度
时间 O(n^3)
空间 O(1)
*/
总结
这道题考察对翻转数组的理解,可以通过 "翻转" 和 "额外添加数组" 的方式来实现
大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com