这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战
前言
继续来一道数组处理的算法题,轮转数组,这个题目个人感觉还是有坑的,一不小心就掉坑里了,下面看看我到底经历了什么
题目描述
给你一个数组,将数组中的元素向右轮转 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]
解题思路
- 这一题乍一看很简单,但一般看起来简单的东西往往不会那么简单,当看到这道题,我便开始了一顿操作,我首先想到的就从新声明一个数组,首先把nums赋值给它,然后再根据k取nums的后几个数据插入新数组,然后再根据nums的长度进行切割,美滋滋,得到了结果,看代码
var rotate = function (nums, k) {
const n = nums.length
let result = [...nums]
for (let i = 0; i < k; i++) {
result.unshift(nums[n - 1 - i])
}
result = result.slice(0, n)
return result
};
复制代码
- 但是万万没想到了,我得到了错误的结果
- 我人傻了,我在vs code中明明是正确的,一顿烦躁,找了好久问题,原来是没理解题的意思。emmm....
- 真是够无语的,原来不需要返回值,需要改变的是原数组,也就是nums,于是我又开始操作
var rotate = function(nums, k) {
k=k%nums.length
const n = nums.length
let result = [...nums]
for (let i = 0; i < k; i++) {
result.unshift(nums[n - 1 - i])
}
for(let i=0;i<n;i++){
nums[i] = result[i]
}
};
复制代码
- 以为美滋滋了,可没想到竟然超时了。。。。在网上搜了一下发现unshift的效率极低,比push操作效率低差不多100倍(如下图),那只能再改代码了,只能声明一个新数组,一个个进行轮转,最后将轮转之后的新数组再赋值给nums,代码如下
var rotate = function(nums, k) {
const n = nums.length;
const newArr = new Array(n);
for (let i = 0; i < n; ++i) {
//这里i+k%n的操作是k有可能比n还大,所以要这么处理
newArr[(i + k) % n] = nums[i];
}
for (let i = 0; i < n; ++i) {
nums[i] = newArr[i];
}
};
复制代码
总结
终于通过了。。。原本以为这题是非常简单的一道题目,没想到一波三折,但总算有些收获,下次遇到问题一定要认真看题,也知道了unshift的效率极低,特别是处理大数组的时候,能不用还是不要用,继续努力,gogogo!!!