目录
一、283 - 移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:输入: nums = [0]
输出: [0]
提示:
- C语言
void moveZeroes(int* nums, int numsSize){
int j = 0;
for (int i = 0; i < numsSize; i++) {
if (nums[i]) {
nums[j] = nums[i];
if (i != j) {
nums[i] = 0;
}
j++;
}
}
}
- Rust
impl Solution {
pub fn move_zeroes(nums: &mut Vec<i32>) {
let mut j = 0;
for i in (0..nums.len()) {
if nums[i] != 0 {
nums[j] = nums[i];
if i != j {
nums[i] = 0;
}
j += 1;
}
}
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(1);
- 运行实况表现出了Rust在运行效率和内存占用率上的优势所在;
二、167 - 两数之和
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
提示:
numbers 按 非递减顺序 排列
仅存在一个有效答案
链接:力扣https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/
- C语言
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
*returnSize = 2; // 检测需要
int* ret = (int*)malloc(sizeof(int) * 2);
int low = 0, high = numbersSize - 1;
while (low < high) {
int sum = numbers[low] + numbers[high];
if (sum == target) {
ret[0] = low + 1, ret[1] = high + 1;
return ret;
} else if (sum < target) {
low++;
} else {
high--;
}
}
ret[0] = 0, ret[1] = 0;
return ret;
}
- Rust
impl Solution {
pub fn two_sum(numbers: Vec<i32>, target: i32) -> Vec<i32> {
let mut ans: Vec<i32> = Vec::new();
let mut l = 0;
let mut r = numbers.len() - 1;
while l < r {
let sum = numbers[l] + numbers[r];
if sum == target {
ans.insert(0, (l + 1) as i32);
ans.insert(1, (r + 1) as i32);
return ans;
} else if sum > target {
r -= 1;
} else {
l += 1;
}
}
ans.insert(0, 0);
ans.insert(1, 0);
ans
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(n);
- 实际运行效果如下,Rust表现依旧惊人...
三、344 - 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
提示:
s[i] 都是 ASCII 码表中的可打印字符
- C 语言
void swap(char* a, char* b) {
char t = *a;
*a = *b;
*b = t;
}
void reverseString(char* s, int sSize){
int i = 0, j = sSize - 1;
while (i < j) {
swap(&s[i], &s[j]);
i++, j--;
}
}
- Rust
// 内置方法
impl Solution {
pub fn reverse_string(s: &mut Vec<char>) {
s.reverse()
}
}
// 手动实现
impl Solution {
pub fn reverse_string(s: &mut Vec<char>) {
let mut i = 0;
let mut j = s.len() - 1;
while i < j {
let t = s[i];
s[i] = s[j];
s[j] = t;
i += 1;
j -= 1;
}
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(1);
- 运行实际效果
也试了试C++,emmm....
四、557 - 反转字符串中的单词 II
给定一个字符串
s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。示例 1:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"示例 2:
输入: s = "God Ding" 输出:"doG gniD"提示:
s
包含可打印的 ASCII 字符。s
不包含任何开头或结尾空格。s
里 至少 有一个词。s
中的所有单词都用一个空格隔开。
链接:力扣
https://leetcode.cn/problems/reverse-words-in-a-string-iii/
- C语言
void rev(char* s, int i, int j) {
while (i < j) {
char t = s[i];
s[i] = s[j - 1];
s[j - 1] = t;
i++, j--;
}
}
char * reverseWords(char * s){
int i = 0, j = 0;
while (s[j] != '\0') {
if (s[j] == ' ') {
rev(s, i, j);
i = (++j);
} else {
j++;
}
}
rev(s, i, j);
return s;
}
- Rust
impl Solution {
pub fn reverse_words(s: String) -> String {
s.split_whitespace()
.map(|x| x.chars().rev().collect::<String>() + " ")
.collect::<String>()
.trim()
.to_string()
}
}
- 时间复杂度 —— O(n);
- 空间复杂度 —— O(1);
- 模拟运行实际时长
每一个不曾起舞的日子,都是对生命的辜负。