- 双指针的使用策略相比二分查找更丰富些;
- 使用Rust时 的注意点果然还是比料想的更多;
- 本专题案例较多,于是便分块记录罢;
目录
Leetcode算法入门之双指针(一)
一、977 - 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100] 示例 2:
输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
提示:
nums 已按非递减顺序排序
使用双指针相向检查数组两端
-
C语言
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* sortedSquares(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int* ans = (int*)malloc(sizeof(int) * (numsSize));
int i = 0, j = numsSize - 1, t = numsSize - 1;
while (i <= j) {
if (nums[i] * nums[i] < nums[j] * nums[j]) {
ans[t] = nums[j] * nums[j];
j--;
} else {
ans[t] = nums[i] * nums[i];
i++;
}
t--;
}
return ans;
}
-
Rust
impl Solution {
pub fn sorted_squares(nums: Vec<i32>) -> Vec<i32> {
let mut i = 0;
let mut j = nums.len() - 1;
let mut ans: Vec<i32> = Vec::new();
for index in 0..nums.len() {
ans.insert(index, 0);
}
let mut t = nums.len() - 1;
while i <= j {
if nums[i] * nums[i] < nums[j] * nums[j] {
ans[t] = nums[j] * nums[j];
j -= 1;
} else {
ans[t] = nums[i] * nums[i];
i += 1;
}
t -= 1;
}
ans
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(n);
二、189 - 轮转数组
给你一个数组,将数组中的元素向右轮转 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]
提示:
使用其中的两种方法来解决
方法一、使用额外数组
-
C语言
void rotate(int* nums, int numsSize, int k) {
int newArr[numsSize];
for (int i = 0; i < numsSize; ++i) {
newArr[(i + k) % numsSize] = nums[i];
}
for (int i = 0; i < numsSize; ++i) {
nums[i] = newArr[i];
}
}
-
Rust
impl Solution {
pub fn rotate(nums: &mut Vec<i32>, k: i32) {
let n = nums.len();
let mut tmp: Vec<i32> = Vec::new();
for i in 0..n {
tmp.insert(i, 0);
}
for i in 0..n {
tmp[(i + k as usize) % n] = nums[i];
}
for i in 0..n {
nums[i] = tmp[i];
}
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(n);
方法二、翻转数组
-
C语言
void rev(int* nums, int l, int r) {
while (l < r) {
int t = nums[l];
nums[l] = nums[r];
nums[r] = t;
l++, r--;
}
}
void rotate(int* nums, int numsSize, int k){
k %= numsSize;
rev(nums, 0, numsSize - 1);
rev(nums, 0, k - 1);
rev(nums, k, numsSize - 1);
}
-
Rust
// 原生算法
pub fn rotate(nums: &mut Vec<i32>, k: i32) {
let k = k as usize % nums.len();
let n = nums.len();
nums.reverse();
// 切片反转
nums[0..k].reverse();
nums[k..n].reverse();
}
// 内置方法
pub fn rotate(nums: &mut Vec<i32>, k: i32) {
let k = k as usize % nums.len();
nums.rotate_right(k);
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(1);
每一个不曾起舞的日子,都是对生命的辜负。