刷题汇总
第一章 数组
第二章 链表
文章目录
前言
数组是连续存储的空间,利用下标索引的方式获取相应数据。
一、双指针
704.二分查找
int left=0,right=nums.size()-1;
while(left<=right){
int mid = left+(right-left)/2;
if(nums[mid]==target) {
return mid;
}
else if(nums[mid]<target){
left=mid+1;
}
else{
right=mid-1;
}
}
88.合并两个有序数组 easy
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int index = m + n - 1;
m--, n--;
while (m >= 0 && n >= 0) {
nums1[index--] = max(nums1[m], nums2[n]);
nums1[m] >= nums2[n] ? m-- : n--;
}
while (n >= 0) {
nums1[n--] = nums2[n];
}
}
33.搜索旋转排序数组
二分查找
15.三数之和
判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有和为 0 且不重复的三元组。
难点是去重!
vector<vector<int>> threeSum(vector<int>& nums) {
//双指针
sort(nums.begin(), nums.end());
vector<vector<int>>result;
for (int i = 0; i < nums.size(); i++) {
//去重
if (nums[i] > 0) return result;
//去重
if (i > 0 && nums[i - 1] == nums[i]) {
continue;
}
int left = i + 1, right = nums.size() - 1;
while (left < right) {
if (nums[i] + nums[left] + nums[right] == 0) { //存储结果,缩小查找范围
result.push_back({ nums[i] , nums[left] , nums[right] });
//去重
while (left < right && nums[right] == nums[right - 1]) right--;
while (left < right && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
else if (nums[i] + nums[left] + nums[right] > 0) {
right--;
// 右值重复,去重
while (left < right && nums[right] == nums[right + 1]) right--;
}
else {
left++;
// 左值重复,去重
while (left < right && nums[left] == nums[left - 1]) left++;
}
}
}
return result;
}
27.移除元素 [快慢指针]
移除元素==保留正确元素
利用快指针找到正确的元素,将正确的元素赋值给慢指针。从而在慢指针的移动范围内都是正确的。
int removeElement(vector<int>& nums, int val){
int left=0,right=0;
for(;right<nums.size();right++){
if(nums[right]!=val){
nums[left++] = nums[right];
}
}
return left;
}
977.有序数组的平方 [左右收缩双指针]
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
vector<int> result(nums.size(), 0);
int index = right;
while (left <= right) {
if (abs(nums[left]) > abs(nums[right])) {
result[index--] = pow(nums[left], 2);
++left;
}
else {
result[index--] = pow(nums[right], 2);
--right;
}
}
return result;
}
补充math中常见函数
1.绝对值函数 fabs ( double x ) 与 abs ( int x )
2.取整函数 floor(double x) 与 ceil(double x)
3.指数函数 x ^y pow( double x , double y )
4.sqrt ( double x )开方函数
5.log( double x) 取对数函数
6.round( double x ) 四舍五入取整函数
209.长度最小的子数组 [滑动窗口](控制流量)
int minSubArrayLen(int target, vector<int>& nums) {
int lenght = INT_MAX, sum = 0;
int left = 0, right = 0;
for (; right < nums.size(); right++) {
sum += nums[right];
while (sum >= target) {
lenght = min(lenght, right - left + 1);
sum -= nums[left++];
}
}
return lenght == INT_MAX ? 0 : lenght;
}
二、排序
56.合并区间
31.下一个排列 【字节跳动】
题目示例非常不全,需要考虑清楚所有情况再解答
思路:题意不可扩展空间,1、第一次查找,从后向前找到第一个
n
u
m
s
[
i
−
1
]
<
n
u
m
s
[
i
]
nums[i-1]<nums[i]
nums[i−1]<nums[i]的
i
i
i;2、第二次查找,从后向前找到第一个比
i
i
i大的值进行交换;3、反转后段数组
r
e
v
e
r
s
e
(
n
u
m
s
.
b
e
g
i
n
(
)
+
i
+
1
,
n
u
m
s
.
e
n
d
(
)
)
;
reverse(nums.begin() + i + 1, nums.end());
reverse(nums.begin()+i+1,nums.end());
41.缺失的第一个正数 【字节跳动+微软】
原地哈希
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
//对负数进行扩值操作
for (auto& num : nums) {
if (num <= 0) num = n + 1;
}
//将小于等于n的元素对应位置变为负数
for (int i = 0; i < n; i++) {
int num = abs(nums[i]);
if (num <= n) nums[num - 1] = -abs(nums[num - 1]);
}
//返回第一个大于零的
for (int i = 0; i < n; ++i) {
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
4.寻找两个正序数组的中位数 【腾讯+字节跳动】 hard
思路寻找两正序数组的分界线!
三、矩阵
54.螺旋矩阵
解题思路:
1、计算完整的圈数round;
2、逐圈计算,分四步;
3、计算可能存在的核心块;
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int row = matrix.size(), col = matrix[0].size();
vector<int>result;
int round = min(row, col) / 2;//顺时针转动的圈数
for (int index = 0; index < round; index++) {
for (int j = index; j < col - (index + 1); j++) {
result.push_back(matrix[index][j]);
}
for (int i = index; i < row - (index + 1); i++) {
result.push_back(matrix[i][col - (index + 1)]);
}
for (int j = col - (index + 1); j > index; j--) {
result.push_back(matrix[row - (index + 1)][j]);
}
for (int i = row - (index + 1); i > index; i--) {
result.push_back(matrix[i][index]);
}
}
if (min(row, col) % 2) {
if (row >= col) {
for (int i = round; i < row - round; i++) {
result.push_back(matrix[i][col / 2]);
}
}
else {
for (int j = round; j < col - round; j++) {
result.push_back(matrix[row / 2][j]);
}
}
}
return result;
}
59.螺旋矩阵II
思路同 54.旋转矩阵
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n, vector<int>(n, 0));
int count = 1;
for (int round = 0; round < n / 2; round++) {
for (int j = round; j < n - (round + 1); j++) {
result[round][j] = count;
count++;
}
for (int i = round; i < n - (round + 1); i++) {
result[i][n - (round + 1)] = count;
count++;
}
for (int j = n - (round + 1); j > round; j--) {
result[n - (round + 1)][j] = count;
count++;
}
for (int i = n - (round + 1); i > round; i--) {
result[i][round] = count;
count++;
}
}
if (n % 2) {
result[n / 2][n / 2] = n * n;
}
return result;
}