文章目录
- 前言
- [一、283. 移动零(HOT100)](#一、283. 移动零(HOT100))
- 二、11.旋转数组的最小数字(剑指Offer)
- 总结
前言
一个本硕双非的小菜鸡,备战24年秋招,计划刷完hot100和剑指Offer的刷题计划,加油!
根据要求,每一道题都要写出两种以上的解题技巧。
一、283. 移动零(HOT100)
Note:快慢指针解题,慢指针指向0的最前一位,快指针遍历,如果快指针指向非0,就与慢指针指向交换(把0换到最后),慢指针再++。
cpp
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int size = nums.size();
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < size; fastIndex++) {
if (nums[fastIndex] != 0) {
swap(nums[fastIndex], nums[slowIndex]);
slowIndex++;
}
}
}
};
遍历整个数组,找出所有非零元素并复制到前面,然后剩下位数补0
Note:
cpp
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int size = nums.size();
int j = 0;
for (int i = 0; i < size; i++) {
if (nums[i] != 0) {
nums[j] = nums[i];
j++;
}
}
while (j < size)
nums[j++] = 0;
}
};
二、11.旋转数组的最小数字(剑指Offer)
Note:剑指offer的写法,有点小麻烦
旋转数组可以划分为两个排序的子数组。用二分查找法,设定一个中间节点。如果中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针的元素。此时数组中最小的元素应该位于该中间元素的后面。
同样,如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针的元素。此时数组中最小的元素应该位于该中间元素的前面。
最终第一个指针指向前面子数组的最后一个元素,第二个指针会指向后面子数组的第一个元素,也就是最小的元素。
有一个特殊情况,三数相同时必须顺序查找
cpp
class Solution {
public:
int minOrder(vector<int>& nums, int startIndex, int endIndex) {
int res = nums[startIndex];
for (int i = startIndex + 1; i <= endIndex; i++) {
if (res > nums[i])
res = nums[i];
}
return res;
}
int findMin(vector<int>& nums) {
int size = nums.size();
if (size == 0) return -1;
int startIndex = 0;
int endIndex = size - 1;
int middle = startIndex;
while (nums[startIndex] >= nums[endIndex]) {
if (endIndex - startIndex == 1) {
middle = endIndex;
break;
}
middle = startIndex + ((endIndex - startIndex) / 2);
if (nums[startIndex] == nums[endIndex] && nums[middle] == nums[startIndex])
return minOrder(nums, startIndex, endIndex);
if (nums[middle] >= nums[startIndex])
startIndex = middle;
else if (nums[middle] <= nums[endIndex])
endIndex = middle;
}
return nums[middle];
}
};
Note:直接二分,感觉还能简洁点哈哈
cpp
class Solution {
public:
int findMin(vector<int>& nums) {
int n = nums.size() - 1;
if (n < 0) return -1;
while (n > 0 && nums[n] == nums[0]) n -- ;
if (nums[n] >= nums[0]) return nums[0];
int l = 0, r = n;
while (l < r) {
int mid = l + r >> 1;
if (nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}
};
总结
祝大家都能学有所成,找到一份好工作!