算法-数组

算法题-数组相关

数组

  记住:先判断边界条件!!!

二分查找

  二分查找采用第一种写法

  第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] ​

  区间的定义这就决定了二分法的代码应该如何写,因为定义 target 在[left, right]区间,所以有如下两点:

  • while (left <= right) 要使用 <= ,因为 left == right 是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个 nums[middle]一定不是 target,那么接下来要查找的左区间结束下标位置就是 middle - 1

  ‍

  ‍

二维数组中的查找_牛客题霸_牛客网 (nowcoder.com)

  在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

  [

  [1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]

  ]

  给定 target = 7,返回 true。

  给定 target = 3,返回 false。

  ‍

1
2
3
4
5
6
7
8
9
10
11
12
13
bool Find(int target, vector<vector<int> >& array) {
// write code here
if(array.size()==0) return false;
int n=array.size();
if(array[0].size()==0) return false;
int m=array[0].size();
for(int i=n-1,j=0;i>=0&&j<m;){
if(array[i][j]>target) i--;
else if(array[i][j]<target) j++;
else return true;
}
return false;
}

  ‍

快慢指针移除元素

题目是给定数组 nums 和一个值 val,原地移除所有数值为 val 的元素,返回移除后数组的新长度

1
2
3
4
5
6
7
8
9
int removeElement(vector<int>& nums, int val) {
int slowIndex=0,fastIndex=0;
while(fastIndex<nums.size()){
if(nums[fastIndex]!=val)
nums[slowIndex++]=nums[fastIndex];
fastIndex++;
}
return slowIndex;
}

写法:先定义快慢指针,然后快指针先走 根据题目条件写不等于时的情况,里面 slowIndex++,最后 fastIndex++

关联题目:26. 删除有序数组中的重复项 - 力扣(LeetCode)

【双指针】比较含退格的字符串 - 比较含退格的字符串 - 力扣(LeetCode)😵 这题需要从后向前遍历 使用双指针

  其他包含双指针的题目:双指针——三数之和、四数之和 剑指 Offer 05. 替换空格 - 力扣(Leetcode)

  151. 反转字符串中的单词 - 力扣(Leetcode) 快慢指针移除元素

滑动窗口

  滑动窗口的题目主要确定三点:

  窗口内是什么?

  如何移动窗口的开始位置?跟随判断条件来

  如何移动窗口的结束位置?​ 跟随循环来 😙

最小滑窗模板

  给定数组 nums,定义滑窗的左右边界 i,j,求满足某个条件的滑窗的最小长度

1
2
3
4
5
6
7
8
9
10
11
while j < len(nums):
判断[i, j]是否满足条件
while 满足条件:
不断更新结果(注意在while内更新!)
i += 1 (最大程度的压缩i,使得滑窗尽可能的小)
j += 1

作者:frostep
链接:https://leetcode.cn/problems/fruit-into-baskets/solution/shen-du-jie-xi-zhe-dao-ti-he-by-linzeyin-6crr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  相关题目:209. 长度最小的子数组 - 力扣(LeetCode) 🤣

  76. 最小覆盖子串 - 力扣(LeetCode)

最大滑窗模板

  给定数组 nums,定义滑窗的左右边界 i,j,求满足某个条件的滑窗的最大长度

1
2
3
4
5
6
7
8
9
10
11
while j < len(nums):
判断[i, j]是否满足条件
while 不满足条件:
i += 1 (最保守的压缩i,一旦满足条件了就退出压缩i的过程,使得滑窗尽可能的大)
不断更新结果(注意在while外更新!)
j += 1

作者:frostep
链接:https://leetcode.cn/problems/fruit-into-baskets/solution/shen-du-jie-xi-zhe-dao-ti-he-by-linzeyin-6crr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  904. 水果成篮 - 力扣(LeetCode)

  ‍

  ‍

  题目汇总:

  ‍

209. 长度最小的子数组 - 力扣(LeetCode) 🤣

这题是求满足和大于等于 target 的最小连续子数组的长度

1
2
3
4
5
6
7
8
9
10
11
12
13
int minSubArrayLen(int target, vector<int>& nums) {
int res=INT32_MAX;
int sum=0,start=0;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
while(sum>=target){
int curlen=i-start+1;
res=min(res,curlen);
sum-=nums[start++];
}
}
return res==INT32_MAX?0:res;
}

904. 水果成篮 - 力扣(LeetCode)

两个篮子装尽可能多的水果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int totalFruit(vector<int>& fruits) {
unordered_map<int,int> s;
int left=0,right=0;
int res=0;
//正常遍历
while(right<fruits.size()){
//right先按照条件走
s[fruits[right]]+=1;
//求最大数目滑动窗口 判断不满足条件的情况
while(s.size()>2){
//压缩左边
s[fruits[left]]--;
if(s[fruits[left]]==0) s.erase(fruits[left]);
++left;
}
res=max(res,right-left+1);
++right;
}
return res;
}

76. 最小覆盖子串 - 力扣(LeetCode)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int> need,win;
for(auto &c:t) ++need[c];
int right=0,left=0,start=0,len=INT_MAX;;
int count=0;
while(right<s.size()){
//先向右扩充
//如果当前right位置字符满足要求就加入
if(need.find(s[right])!=need.end()){
++win[s[right]];
if(win[s[right]]==need[s[right]]) ++count;
}
//然后满足要求后左边收缩
while(count==need.size()){
//更新
if(len>right-left+1){
len=right-left+1;
start=left;
}
//收缩
if(need.find(s[left])!=need.end()){
if(win[s[left]]==need[s[left]]) --count;
--win[s[left]];
}
++left;
}
++right;
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};

  ‍

  ‍

排序算法

归并排序

  数组中的逆序对_牛客题霸_牛客网 (nowcoder.com)

  ​image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @return int整型
*/
void merge(vector<int>& nums,int left,int mid,int right,int &res){
vector<int> tmp(right-left+1);
int i=left,j=mid+1;
int k=0;
while(i<=mid&&j<=right){ //* <=
if(nums[i]>nums[j]){
tmp[k++]=nums[j++];
res+=(mid-i+1);
res%=1000000007;
}else{
tmp[k++]=nums[i++];
}
}
while(i<=mid) tmp[k++]=nums[i++];
while(j<=right) tmp[k++]=nums[j++];
for(int idx=left,j=0;j<k;idx++){
nums[idx]=tmp[j++];
}
}
void mergeSort(vector<int>& nums,int left,int right,int &res){
*if(left>=right) return; //>=
int mid=left+((right-left)>>1);
mergeSort(nums, left,mid,res);
mergeSort(nums,mid+1,right,res);
merge(nums,left,mid,right,res);
}
int InversePairs(vector<int>& nums) {
// write code here
int res=0;
mergeSort(nums,0,nums.size()-1,res);
return res;
}
};

  ‍


算法-数组
https://shanhainanhua.github.io/2023/08/25/算法-数组/
作者
wantong
发布于
2023年8月25日
许可协议