双指针
【977】有序数组的平方
| Category | Difficulty | Likes | Dislikes |
|---|---|---|---|
| algorithms | Easy (72.54%) | 257 | - |
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
个人解法
var sortedSquares = function (nums) {
for (let i in nums) {
nums[i] = nums[i] * nums[i];
}
nums.sort((a, b) => a - b);
return nums;
};
| 通过 | 116 ms | 45.8 MB | JavaScript |
|---|
分析
个人解法为暴力解法。因为数组按非递减顺序排序,还可以尝试双指针法。
数组按非递减顺序排序,元素平方后的最大值必在两端。
定义数组左右端点的下标为left、right,比较两端点平方后值的大小。
将较大值插入新数组arr的开头,直至left=right。
第二种解法
var sortedSquares = function (nums) {
let [left, right] = [0, nums.length - 1];
let arr = [];
while (left <= right) {
if (nums[left] * nums[left] < nums[right] * nums[right]) {
arr.unshift(nums[right] * nums[right]);
right--;
} else {
arr.unshift(nums[left] * nums[left]);
left++;
}
}
return arr;
};
| 通过 | 160 ms | 44.7 MB | JavaScript |
|---|
分析
算法的时间复杂度降低。
另外,还可以使用绝对值函数Math.abs()。
const left = Math.abs(nums[i])
const right = Math.abs(nums[j])
【189】旋转数组
| Category | Difficulty | Likes | Dislikes |
|---|---|---|---|
| algorithms | Medium (45.38%) | 1042 | - |
给定一个数组,将数组中的元素向右移动 k **个位置,其中 k **是非负数。
个人解法
var rotate = function (nums, k) {
while (k > nums.length) {
k = k - nums.length;
}
let arr = nums.splice(nums.length - k, k);
arr.reverse();
for (let item of arr) {
nums.unshift(item);
}
return nums;
};
分析
个人解法为暴力解法。还可以考虑一开始就反转数组。
思路:
以nums = [1,2,3,4,5,6,7], k = 3为例。数组反转后为nums = [7,6,5,4,3,2,1],需要移动到前面的k位数组元素这时移到了数组前部,便于操作。
此时K位数组元素7,6,5、余下数组元素4,3,2,1的顺序,与目标结果的顺序相反,那么再次反转这两个“小数组”即可。
tips:
反转数组可以引入双指针法实现,交换每个头尾元素即可:定义数组开头和结尾的下标,定义一个中间值temp用于暂存结尾元素值,方便交换。
单独写一个反转数组的函数,调用三次,比较简洁方便。
对于k大于数组长度的情况,实际就是元素移动若干个数组长度后,再移动余下数字的长度。
第二种解法
var rotate = function (nums, k) {
while (k > nums.length) {
k = k - nums.length;
}
const reverse = (arr, start, end) => {
while (start < end) {
let temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
return nums;
};
| 通过 | 96 ms | 44.9 MB | JavaScript |
|---|