【LeetCode】

目录

  • 知识框架
  • LeetCode
  • No.1 按照顺序的结果没坚持下来
    • [1. 两数之和](https://leetcode.cn/problems/two-sum/)
    • [3. 无重复字符的最长子串](https://leetcode.cn/problems/longest-substring-without-repeating-characters/)
    • [4. 寻找两个正序数组的中位数](https://leetcode.cn/problems/median-of-two-sorted-arrays/)
    • [5. 最长回文子串](https://leetcode.cn/problems/longest-palindromic-substring/)
    • [6. N 字形变换](https://leetcode.cn/problems/zigzag-conversion/)
    • [7. 整数反转](https://leetcode.cn/problems/reverse-integer/)
  • No.2 动态规划
    • 5.最长回文串:
    • 42.接雨水
  • No.3 周赛
    • 第 79 场双周赛
      • 6083.判断─个数的数字计数是否等于数位的值
      • 6084.最多单词数的发件人
      • 6085.道路的最大总重要性
      • 10011.以组为单位订音乐会的门票
    • 第 301 场周赛
      • 6112.装满杯子需要的最短总时长
      • 6113.无限集中的最小数字
    • 第304场周赛:
      • 使数组中所有元素都等于零
      • 分组的最大数量
      • 找到离给定两个节点最近的节点
      • 图中的最长环
    • 第306场周赛:
      • 矩阵中的局部最大值
      • 边积分最高的节点
      • 根据模式串构造最小数字
      • 统计特殊整数:数位dp
    • 第309场周赛:
        • [6167. 检查相同字母间的距离](https://leetcode.cn/problems/check-distances-between-same-letters/)
        • [6168. 恰好移动 k 步到达某一位置的方法数目](https://leetcode.cn/problems/number-of-ways-to-reach-a-position-after-exactly-k-steps/)
      • [2401. 最长优雅子数组](https://leetcode.cn/problems/longest-nice-subarray/)
      • [2402. 会议室 III](https://leetcode.cn/problems/meeting-rooms-iii/)
    • 第 310 场周赛:
      • 子字符串的最优划分
      • 将区间分为最少组数
      • [最长递增子序列 II](https://leetcode.cn/problems/longest-increasing-subsequence-ii/)
    • 第312场周赛
        • [2418. 按身高排序](https://leetcode.cn/problems/sort-the-people/)
      • 按位与最大的最长子数组
  • No.4 字符串
    • 二进制数的间距:
    • [3. 无重复字符的最长子串](https://leetcode.cn/problems/longest-substring-without-repeating-characters/):滑动窗口+哈希表
    • [20. 有效的括号](https://leetcode.cn/problems/valid-parentheses/):栈的对称
  • No.5 前缀和
    • 前缀和+哈希表
    • 滑动窗口模板
    • [209. 长度最小的子数组](https://leetcode.cn/problems/minimum-size-subarray-sum/):滑动窗口
    • [238. 除自身以外数组的乘积](https://leetcode.cn/problems/product-of-array-except-self/) 前缀和+后缀和
    • [1004. 最大连续1的个数 III](https://leetcode.cn/problems/max-consecutive-ones-iii/):滑动窗口
    • [1124. 表现良好的最长时间段](https://leetcode.cn/problems/longest-well-performing-interval/):前缀和+单调栈
    • [724. 寻找数组的中心下标](https://leetcode.cn/problems/find-pivot-index/):前缀和
    • [560. 和为 K 的子数组](https://leetcode.cn/problems/subarray-sum-equals-k/):前缀和+哈希表
    • [1248. 统计「优美子数组」](https://leetcode.cn/problems/count-number-of-nice-subarrays/):前缀和+哈希表
    • [974. 和可被 K 整除的子数组](https://leetcode.cn/problems/subarray-sums-divisible-by-k/):前缀和+哈希表
    • [523. 连续的子数组和](https://leetcode.cn/problems/continuous-subarray-sum/):前缀和+哈希表
    • [930. 和相同的二元子数组](https://leetcode.cn/problems/binary-subarrays-with-sum/):前缀和+哈希表
    • [904. 水果成篮](https://leetcode.cn/problems/fruit-into-baskets/):滑动窗口+哈希表
    • [904. 水果成篮](https://leetcode.cn/problems/fruit-into-baskets/):滑动窗口+哈希表

知识框架

LeetCode

No.1 按照顺序的结果没坚持下来

1. 两数之和

主要是 哈希表进行优化;

重点是 map的find; it->second ;以及 it != hastable.end();

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        maphastable;
        for(int i=0;ires;
        for(int i=0;i=it->second){
                    continue;
                }
                res.push_back(i);
                res.push_back(it->second);
                break;
            }
        }
        return res;
        
    }
};

3. 无重复字符的最长子串

滑动窗口:

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0) return 0;
        unordered_set lookup;
        int maxStr = 0;
        int left = 0;
        for(int i = 0; i < s.size(); i++){
            while (lookup.find(s[i]) != lookup.end()){//找到的话;
                lookup.erase(s[left]);
                left ++;
            }
            maxStr = max(maxStr,i-left+1);
            lookup.insert(s[i]);
    }
        return maxStr;
        
    }
};

4. 寻找两个正序数组的中位数

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        int m=nums1.size();
        int n = nums2.size();

        vectorans;
        int pos1=0,pos2=0;
        while(pos1=m){
            for( ; pos2=n){
            for( ; pos1

5. 最长回文子串

中心扩散法子;

1、从每一个位置出发,向两边扩散即可。遇到不是回文的时候结束

首先往左寻找与当期位置相同的字符,直到遇到不相等为止。
然后往右寻找与当期位置相同的字符,直到遇到不相等为止。
最后左右双向扩散,直到左和右不相等。

为什么是这样呢??

如果长度是单数,那么很明显,最中心的是一个字符;而结果是偶数 的话,那么中心就是两个字符,并且相同。

class Solution {
public:
    string longestPalindrome(string s) {
        //中心扩散法:从每个字母开始 进行扩散遍历判断;
        int n=s.size();
        int left = 0;
        int right = 0;
        int len = 1; //记录选择的字符字串长度
        int maxStart = 0;
        int maxLen = 0;

        for (int i = 0; i < n; i++) {
            len=1;
            left = i - 1;
            right = i + 1;
            while (left >= 0 && s[left]==s[i]) {
                len++;
                left--;
            }
            while (right < n && s[right]==s[i]) {
                len++;
                right++;
            }
            while (left >= 0 && right < n && s[left]==s[right]) {
                len = len + 2;
                left--;
                right++;
            }
            if (len > maxLen) {
                maxLen = len;
                maxStart = left;
            }
        }
        return s.substr(maxStart+1,maxLen);

    }
};

6. N 字形变换


7. 整数反转

弹出最后的数字,

压入;

while循环进行倒转;;;

class Solution {
public:
    int reverse(int x) {
        char resStar='0';
        if(x<0) resStar='-';
        x=abs(x);

        int temp=0;
        int res=0;

        while(x!=0){
            temp=x%10;
            x=x/10;
            
            res=res*10+temp;
            if(res>214748364){
                return 0;
            }
        }
        if(resStar=='-'){
            return -res;
        }else{
            return res;
        }

    }
};

No.2 动态规划

5.最长回文串:

给你一个字符串 s,找到 s 中最长的回文子串。

对于一个子串而言,如果它是回文串,并且长度大于2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串“ababa”,如果我们已经知道“bab”是回文串,那么“ababa”一定是回文串,这是因为它的首尾两个字母都是“a”。
根据这样的思路,我们就可以用动态规划的方法解决本题。我们用P(i,j)表示字符串s的第i到j个字母组成的串 (下文表示成s[i:j])是否为回文串:P(i,j)一false,其它情况这里的「其它情况」包含两种可能性:. s[i,j]本身不是一个回文串;或者 i> j,此时s[i,j]本身不合法。
那么我们就可以写出动态规划的状态转移方程:
P(i,j)=P(i+1,j- 1)乘以(S:== S;)

也就是说,只有s[i+1 :j-1]是回文串,并且s 的第i和j个字母相同时,s[i :j才会是回文串。上文的所有讨论是建立在子串长度大于2的前提之上的,我们还需要考虑动态规划中的边界条件,即子串的长度为1或2。对于长度为1的子串,它显然是个回文串;对于长度为2的子串,只要它的两个字母相同,它就是一个回文串。因此我们就可以写出动态规划的边界条件:
P(i,i)= true
P(i,i+1)=(S== Si+1)
根据这个思路,我们就可以完成动态规划了,最终的答案即为所有P(i,j)= true中j-i+1(即子串长度)的最大值。注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。

#include
using namespace std;
#define N 10001

int main()
{
    int dp[N][N];
    string s;
    cin>>s;
    if(s.size()<2){
        //则本身为回文串;
    }
    int n=s.size();
    int maxlen=1;
    int begin=0;
    // dp[i][j] 表示 s[i..j] 是否是回文串
    // 初始化:所有长度为 1 的子串都是回文串
        for (int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }
        // 递推开始
        // 先枚举子串长度
        for(int L=2;L<=n;L++){
            for(int i=0;i=n){
                    break;
                  }
                  if(s[i]!=s[j]){
                    dp[i][j]=0;

                  }else{
                    if(j-i<3){
                        dp[i][j]=1;
                    }else{
                        dp[i][j]=dp[i+1][j-1];
                    }

                  }
                // 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                if (dp[i][j] && j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                    begin = i;
                }
            }
        }


return 0;
}

42.接雨水

每个位置能够存储的水的量为两步:先找左边的墙的最高的高度h1,再找右边的墙的最高的高度h2;然后计算min(h1,h2)-height;
int trap(vector& height)
{
    int ans = 0;
    int size = height.size();
    //0位置和size-1位置都不行;
    for (int i = 1; i < size - 1; i++) {
        int max_left = 0, max_right = 0;
        for (int j = i; j >= 0; j--) { //Search the left part for max bar size
            max_left = max(max_left, height[j]);
        }
        for (int j = i; j < size; j++) { //Search the right part for max bar size
            max_right = max(max_right, height[j]);
        }
        ans += min(max_left, max_right) - height[i];
    }
    return ans;
}

No.3 周赛

第 79 场双周赛

6083.判断─个数的数字计数是否等于数位的值

#include
using namespace std;
#define N 10001
string s;
int check(int x){
    int count=0;
    for(auto i:s){
        if(i-'0'==x)count++;
    }
    return count;
}
int main()
{
    cin>>s;
    int flag=0;
    for(int i=0;i

6084.最多单词数的发件人

//在一串字符单词中比如:messages = ["Wonderful day Alice"],
//那么如何统计单词的个数,:即只需要统计空格的数量+1;

6085.道路的最大总重要性

思路及算法
计算每个城市的出现次数,排序后,次数多的分配当前最大的值
这里直接加到大根堆中弹出,效果与排序一致

10011.以组为单位订音乐会的门票


第 301 场周赛

6112.装满杯子需要的最短总时长

#include 
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
int n,m,t,k,d;
int x,y,z;
char ch;
string s;
vectorv[N];
int main()
{
    vectorcount;
    for(int i=0;i<3;i++){
        cin>>x;
        count.push_back(x);
    }
    int ans=0;
    //进行贪心:每次装入需求最多的两杯:
    while(count[0]!=0||count[1]!=0||count[2]!=0){
        sort(count.begin(),count.end());
        if(count[2]>0)count[2]--;
        if(count[1]>0)count[1]--;
        ans++;
    }
    cout<

6113.无限集中的最小数字


第304场周赛:

使数组中所有元素都等于零

//对于N要进行适应性的更改,对于字段错误
#include
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,k,g,d,t;
int x,y,z;
char ch;
string str;
vectorv[N];

int main() {

	vectornums;
	setsc;
	for(auto p:nums)sc.insert(p);
	int res=0;
	for(auto p:sc){
		if(p>0)res++;
	}
	cout<

分组的最大数量

//对于N要进行适应性的更改,对于字段错误
#include
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,k,g,d,t;
int x,y,z;
char ch;
string str;
vectorv[N];

int main() {

	sort(grades.begin(),grades.end());
	int res=0;
	int num=grades.size();
	for(int i=1; ;i++){
		if(num>=i){
			res++;
			num=num-i;
		}else{
			break;
		}
	}
	return res;

	return 0;
}

找到离给定两个节点最近的节点

最短路径问题:

「最短路径」算法有 最短路径-Dijkstra 和 无权值最短路径算法(BFS)

「Dijkstra」适用于加权有向图,没有负权重边,且无环,一般是求起点到其它所有点的最短路径,也可以改进为求两点的最短路径

「无权值最短路径算法(BFS)」适用于无权有向图,可以有环,一般是求两点的最短路径,也可以改进为求起点到其它所有点的最短路径

对于本题,每条边的权重均为 1,所以可以看作为无权值,我们使用上述的第二种方法「无权值最短路径算法(BFS)」

由于点与点之间最多只有一条边,所以可以简化「无权值最短路径算法(BFS)」

public int closestMeetingNode(int[] edges, int node1, int node2) {
    int n = edges.length;
    // 点 node1 和 node2 到其它所有点的最短路径
    int[] dist1 = getDist(edges, node1);
    int[] dist2 = getDist(edges, node2);
    int ans = -1, min = (int) 1e5 + 7;
    // 遍历可选择的「中间点」
    for (int i = 0; i < n; i++) {
        // 分别为 node1 和 node2 到 i 的最短路径
        int d1 = dist1[i], d2 = dist2[i];
        // 如果有一方到不了,则跳过
        if (d1 == -1 || d2 == -1) continue;
        int max = Math.max(d1, d2);
        if (max < min) {
            min = max;
            ans = i;
        }
    }
    return ans;
}
// 求点 s 到其它所有点的最短路径
private int[] getDist(int[] edges, int s) {
    int d = 0;
    int[] dist = new int[edges.length];
    Arrays.fill(dist, -1);
    while (s != -1) {
        // 已经访问,考虑「环」的存在
        if (dist[s] != -1) break;
        dist[s] = d++;
        // 下一个点
        s = edges[s];
    }
    return dist;
}

图中的最长环

环问题:

图的最大环最长链 - Rogn - 博客园 (cnblogs.com)

	这是一个模板问题、:
最长环问题:
    
  
最长链问题:
    

第306场周赛:

矩阵中的局部最大值

class Solution {
public:
    vector> largestLocal(vector>& grid) {
        vector>res;
        vectorans;
        int n=grid.size();
        int m=grid[0].size();
        int len=n-3+1;
        //以 多少个位置为左上角的起点构成3*3矩阵
        // 每一行
        for(int i=0;i

边积分最高的节点

class Solution {
public:
    int edgeScore(vector& edges) {
        int n=edges.size();
        long long sum[n];
        memset(sum,0,sizeof(sum));
        for(int i=0;imax){
                max=sum[i];
                loc=i;
            }
        }
        return loc;
    }
};

根据模式串构造最小数字


统计特殊整数:数位dp


第309场周赛:

6167. 检查相同字母间的距离

// 蛀牙是进行  字符字母 与数字的转化;和


    ch='a';
    char cc = ch+1;
    cout<& distance) {
        setsc;
        for(auto i:s)sc.insert(i);
        for(auto i:sc){
            int num=0;
            for(int j=0;j

6168. 恰好移动 k 步到达某一位置的方法数目

//对于N要进行适应性的更改,对于字段错误
#include
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
int n,m,k,g,d;
int x,y,z,t;
char ch;
string str;
vectorv[N];
long long mod = 1000000000+7;
long long sum = 0;

int endstop;
void dfs(int index,int citime,long long &sum){

    if(citime>x>>endstop;

    cin>>k;
    dfs(x,0,sum);
    cout<

2401. 最长优雅子数组

滑动窗口:

res = max(res, right - left +1 ); 这个是关键;res记录过去(因为只是要结果。

class Solution {
public:
    int longestNiceSubarray(vector& nums) {
        int n = nums.size();
        if(n == 1)return 1;
        int res = 1;
        int left = 0;//记录当前优雅子数组
        for(int right = 1;right < n;++i){
            for(int i = right - 1;i >= left;--i){
                if(nums[right] & nums[i]){
                    //说明right指向的位置和i不可以构成优雅子数组
                    left = i + 1;
                    break;
                }
            }
            res = max(res,right - left + 1);
        }
        return res;
    }
};

作者:sdy-r
链接:https://leetcode.cn/problems/longest-nice-subarray/solution/by-sdy-r-glyh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2402. 会议室 III

1.使用sort函数,重写排序规则。

struct node{
	int x;
	int y;
}a[10];
 
bool cmp(node a, node b)
{
	return a.x > b.x; //从大到小排列
//  return a.x < b.x;  从小到大排列 
}

2.在结构体中自定义排序,重小于号

struct node{
	int x;
	int y;
	bool operator<(const node &a) const{
		return x < a.x; //从大到小排序 
	                   //  x > a.x;  //从小到大排序 
	}
	//这里的排序是根据每个结构体内部的x进行排序 
}a[10];


3、优先队列排序(priority_queue)的使用:

结构体排序 + 优先队列排序(priority_queue)

// 优先级队列问题。

第 310 场周赛:

子字符串的最优划分

很经典的题目

将区间分为最少组数

很经典

最长递增子序列 II

线段树知识。。

第312场周赛

2418. 按身高排序

class Solution {
public:
    vector sortPeople(vector& names, vector& heights) {
        vectorpos;
        vectorheightssss;
        heightssss = heights;
        sort(heights.begin(),heights.end());
        int n =heights.size();
        for(int i=n-1;i>=0;i--){
            for(int j=0;jnameee;
        for(int i=0;i

按位与最大的最长子数组


按位与最大的最长子数组


好路径的数目


No.4 字符串

二进制数的间距:

#include 
using namespace std;
#define N 100100
#define inf 0x3f3f3f3f
int x,y,z;
int n,m,s,d,k;
string str;
char ch;
vectorv[N];

int main()
{
    cin>>n;
    vectorans;
    while(n!=0){
        ans.push_back(n%2);
        n=n/2;
    }
    for(int i=ans.size()-1;i>=0;i--){
        cout<

3. 无重复字符的最长子串:滑动窗口+哈希表

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        mapmp;
        int n=s.size();
        int res=0;
        int right=0,left=0;
        int flag=0;
        for(;right

20. 有效的括号:栈的对称

class Solution {
public:
    bool isValid(string s) {
        bool flag = true;
        int n=s.size();
        if(n%2!=0)return false;
        stacks1,s2;
        for(int i=0;i

No.5 前缀和

【动画模拟】一文秒杀七道题 - 连续的子数组和 - 力扣(LeetCode)

前缀和+哈希表

要想着变化方程式,,比如哈希表的那个 pre[i] - pre[j-1] = k 变化为 pre[i] - k ; 找存在。

滑动窗口模板

滑动窗口是什么呢? 可能是 一个start指针,一个end指针,进而进行滑动,根据一些题目条件进行移动。。

《挑战程序设计竞赛》这本书中把滑动窗口叫做「虫取法」,我觉得非常生动形象。因为滑动窗口的两个指针移动的过程和虫子爬动的过程非常像:前脚不动,把后脚移动过来;后脚不动,把前脚向前移动。

我分享一个滑动窗口的模板,能解决大多数的滑动窗口问题:

def findSubArray(nums):
    N = len(nums) # 数组/字符串长度
    left, right = 0, 0 # 双指针,表示当前遍历的区间[left, right],闭区间
    sums = 0 # 用于统计 子数组/子区间 是否有效,根据题目可能会改成求和/计数
    res = 0 # 保存最大的满足题目要求的 子数组/子串 长度
    while right < N: # 当右边的指针没有搜索到 数组/字符串 的结尾
        sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数
        while 区间[left, right]不符合题意: # 此时需要一直移动左指针,直至找到一个符合题意的区间
            sums -= nums[left] # 移动左指针前需要从counter中减少left位置字符的求和/计数
            left += 1 # 真正的移动左指针,注意不能跟上面一行代码写反
        # 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串
        res = max(res, right - left + 1) # 需要更新结果
        right += 1 # 移动右指针,去探索新的区间
    return res


滑动窗口中用到了左右两个指针,它们移动的思路是:以右指针作为驱动,拖着左指针向前走。右指针每次只移动一步,而左指针在内部 while 循环中每次可能移动多步。右指针是主动前移,探索未知的新区域;左指针是被迫移动,负责寻找满足题意的区间。

模板的整体思想是:

  1. 定义两个指针 leftright 分别指向区间的开头和结尾,注意是闭区间;定义 sums 用来统计该区间内的各个字符出现次数;

  2. 第一重 while 循环是为了判断 right 指针的位置是否超出了数组边界;当 right 每次到了新位置,需要增加 right 指针的求和/计数;

  3. 第二重 while 循环是让 left 指针向右移动到 [left, right] 区间符合题意的位置;当 left 每次移动到了新位置,需要减少 left 指针的求和/计数;

  4. 在第二重 while 循环之后,成功找到了一个符合题意的 [left, right] 区间,题目要求最大的区间长度,因此更新 res 为 max(res, 当前区间的长度) 。

  5. right 指针每次向右移动一步,开始探索新的区间。

  6. 模板中的 sums 需要根据题目意思具体去修改,本题是求和题目因此把sums 定义成整数用于求和;如果是计数题目,就需要改成字典用于计数。当左右指针发生变化的时候,都需要更新 sums

209. 长度最小的子数组:滑动窗口

class Solution {
public:
    int minSubArrayLen(int s, vector& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int ans = INT_MAX;
        int start = 0, end = 0;
        int sum = 0;
        while (end < n) {
            sum += nums[end];
            while (sum >= s) {
                ans = min(ans, end - start + 1);
                sum -= nums[start];
                start++;
            }
            end++;
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

238. 除自身以外数组的乘积 前缀和+后缀和

class Solution {
public:
    vector productExceptSelf(vector& nums) {
        int n=nums.size();
        int sumq[n];
        int sumh[n];
        for(int i=0;i=0;i--){
            if(i==n-1)sumh[i]=nums[i];
            else sumh[i]=sumh[i+1]*nums[i];
        }
        vectorans;
        ans.push_back(sumh[1]);
        for(int i=1;i

1004. 最大连续1的个数 III:滑动窗口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oGuEapDr-1679671888186)(D:/Typora/images/image-20221020153751247.png)]

class Solution {
public:
    int longestOnes(vector& nums, int k) {
        int n=nums.size();
        int left = 0,right=0,sum=0;
        int res=0;
        for( ;rightk){
                if(nums[left]==0)sum--;
                left++;
            }
            res=max(res,right-left+1);
        }
        return res;
    }
};

1124. 表现良好的最长时间段:前缀和+单调栈

// 首先尝试滑动窗口 进行 求解,,但是不行,只能通过一半。
//我一开始也以为是滑动窗口,但想这样的case:[1,2,3,9,9,9,9,9];类似这样的滑窗做不了
class Solution {
public:
    int longestWPI(vector& hours) {
        int n=hours.size();
        int left=0,right=0,sum1=0;
        int res=0;
        for(;right8)sum1++;
            else sum1--;
            while(sum1<=0&&left<=right){
                if(sum1<=0&&left==right)break;
                if(hours[left]>8)sum1--;
                else sum1++;
                left++;
            }
            
            res=max(res,right-left+1);
        }
        return res;

    }
};



// 下面的有点偏暴力了
class Solution {
public:
    int longestWPI(vector& hours) {
        int n=hours.size();
        int sum[n];
        int nums[n];
        for(int i=0;i8)nums[i]=1;
            else nums[i]=-1;
        }
        sum[0]=nums[0];
        for(int i=1;i0){   //特别是这个判断条件的  +nums[i]
                    res=max(res,j-i+1);
                }
            }
        }
        return res;
    }
};

724. 寻找数组的中心下标:前缀和

class Solution {
public:
    int pivotIndex(vector& nums) {
        int n=nums.size();
        int sum[n+1];
        sum[0]=0;
        for(int i=0;ians;
        for(int i=1;i<=n;i++){
            int left = sum[i-1];
            int right = sum[n]-sum[i];
            if(left==right){
                ans.push_back(i-1);
            }
        }
        if(ans.size()==0)return -1;
        else return ans[0];
    }
};

560. 和为 K 的子数组:前缀和+哈希表

思路:其实我们现在这个题目和两数之和原理是一致的,只不过我们是将所有的前缀和该前缀和出现的次数存到了 map 里。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ikxzAXnr-1679671888186)(D:/Typora/images/image-20221025191243786.png)]

class Solution {
public:
    int subarraySum(vector& nums, int k) {
        mapmp;
        mp[0]=1;//是从开始到自身即pre[i]-k=0;即
        int n=nums.size();
        int pre[n+1];
        pre[0]=0;
        int res=0;
        for(int i=1;i<=n;i++){
            pre[i]=pre[i-1]+nums[i-1];
            if(mp.find(pre[i]-k)!=mp.end()){
                res+=mp[pre[i]-k];
            }
            mp[pre[i]]++;
        }
        return res;
    }
};

1248. 统计「优美子数组」:前缀和+哈希表

思路”要想着变化方程式;;;

class Solution {
public:
    int numberOfSubarrays(vector& nums, int k) {
        int res=0;
        int n=nums.size();
        int pre[n+1];
        pre[0]=0;
        mapmp;
        mp[0]=1;
        for(int i=0;i

974. 和可被 K 整除的子数组:前缀和+哈希表

其中 巧妙的 还是 方程变化。 以及对 负数的处理。

class Solution {
public:
    int subarraysDivByK(vector& nums, int k) {
        mapmp;
        mp[0]=1;
        int n=nums.size();
        int pre[n+1];
        pre[0]=0;
        int res=0;
        for(int i=1;i<=n;i++){
            // 注意负数 的问题。
            pre[i]=pre[i-1]+nums[i-1];
            if(mp.find((pre[i]%k+k)%k)!=mp.end()){
                res+=mp[(pre[i]%k+k)%k];
            }
            mp[(pre[i]%k+k)%k]++;
        }
        return res;

    }
};

523. 连续的子数组和:前缀和+哈希表

class Solution {
public:
    bool checkSubarraySum(vector& nums, int k) {
        int n = nums.size();
        mapmp;
        mp[0]=1;
        int pre[n+1];
        pre[0]=0;
        int res = 0;
        pre[1]=pre[0]+nums[0];
        for(int i=2;i<=n;i++){
            pre[i]=pre[i-1]+nums[i-1];
            if(mp.find(pre[i]%k)!=mp.end()){
                res+=mp[pre[i]%k];
            }
            mp[pre[i-1]%k]++; // 因为个数限制。
        }
        if(res==0)return false;
        else return true;

    }
};

930. 和相同的二元子数组:前缀和+哈希表

class Solution {
public:
    int numSubarraysWithSum(vector& nums, int goal) {
        mapmp;
        mp[0]=1;
        int n=nums.size();
        int pre[n+1];
        pre[0]=0;
        int res=0;
        for(int i=1;i<=n;i++){
            pre[i]=pre[i-1]+nums[i-1];
            if(mp.find(pre[i]-goal)!=mp.end()){
                res+=mp[pre[i]-goal];
            }
            mp[pre[i]]++;           
        }
        return res;

    }
};

904. 水果成篮:滑动窗口+哈希表

class Solution {
public:
    int totalFruit(vector& fruits) {
        int res = 0;
        int n =fruits.size();
        int right=0,left=0;
        setsc;
        mapmp;
        for(;right2){
                mp[fruits[left]]--;
                if(mp[fruits[left]]==0)sc.erase(fruits[left]);
                left++;
            }
            res=max(res,right-left+1);
        }
        return res;
    }
};

1]=pre[0]+nums[0];
for(int i=2;i<=n;i++){
pre[i]=pre[i-1]+nums[i-1];
if(mp.find(pre[i]%k)!=mp.end()){
res+=mp[pre[i]%k];
}
mp[pre[i-1]%k]++; // 因为个数限制。
}
if(res==0)return false;
else return true;

}

};






## [930. 和相同的二元子数组](https://leetcode.cn/problems/binary-subarrays-with-sum/):前缀和+哈希表

```c++
class Solution {
public:
    int numSubarraysWithSum(vector& nums, int goal) {
        mapmp;
        mp[0]=1;
        int n=nums.size();
        int pre[n+1];
        pre[0]=0;
        int res=0;
        for(int i=1;i<=n;i++){
            pre[i]=pre[i-1]+nums[i-1];
            if(mp.find(pre[i]-goal)!=mp.end()){
                res+=mp[pre[i]-goal];
            }
            mp[pre[i]]++;           
        }
        return res;

    }
};

904. 水果成篮:滑动窗口+哈希表

class Solution {
public:
    int totalFruit(vector& fruits) {
        int res = 0;
        int n =fruits.size();
        int right=0,left=0;
        setsc;
        mapmp;
        for(;right2){
                mp[fruits[left]]--;
                if(mp[fruits[left]]==0)sc.erase(fruits[left]);
                left++;
            }
            res=max(res,right-left+1);
        }
        return res;
    }
};

你可能感兴趣的:(#,原始者-竭力耶,leetcode,算法,职场和发展)