Leetcode 4.16

1.找两个和为目标值且不重叠的子数组

找两个和为目标值且不重叠的子数组
初始化变量:

  • sum:用于存储当前左边界 l 到右边界 r 之间的子数组和。
  • r:初始化为数组的最后一个元素的索引,表示初始的右边界。
  • ans:用于存储最小的两个子数组长度和,初始化为一个较大的数(2e5),确保后面能找到更小的值来更新它。
  • len:一个数组,用于存储从当前位置到数组末尾的子数组的最小长度。其初始值都设为 2e5。

滑动窗口遍历数组:

  • 外部循环从右向左遍历数组,l 表示当前子数组的左边界。
  • 在每次外部循环中,sum 从 l 开始累加元素,直到 sum 大于 target。
  • 如果 sum 大于 target,则通过减少右边界 r 的元素来缩小子数组的范围,直到 sum 再次小于或等于 target。

检查当前子数组和:

  • 如果 sum 等于 target,则找到了一个和为 target 的子数组。 计算当前子数组的长度 curlen,它是 r - l +1。
  • 更新 ans 为 ans 和 curlen + lenr + 1 中的较小值。这里 lenr + 1 表示从 r + 1到数组末尾的子数组的最小长度。因为我们想找到两个不相交的子数组,所以加上从 r + 1 开始的子数组的最小长度是合理的。
  • 更新lenl 为 curlen 和 lenl + 1 中的较小值。这是因为从 l 开始到数组末尾的子数组的最小长度要么是当前子数组的长度,要么是从 l + 1 开始到数组末尾的子数组的最小长度。

返回结果:

  • 如果找到了两个符合条件的子数组,则返回 ans。
  • 否则,返回 -1,表示没有找到这样的子数组。
    这段代码的关键点在于使用了滑动窗口和动态规划的思想。通过维护一个 len 数组来记录从当前位置到数组末尾的子数组的最小长度,避免了重复计算。
cpp 复制代码
class Solution {
public:
    int minSumOfLengths(vector<int>& arr, int target) {
        //从右往左遍历
        //用l和r指针控制位置,选择不相交区域
        int r = arr.size() - 1; int l = r;
        //用vector<int>保存当前位置等于target的最小子数组长度
        //加一是因为需要比对r+1的值
        vector<int> len(arr.size() + 1, 2e5);
        //ans保存两个最短子数组长度和
        int ans = 2e5;
        //保留l到r位置的和
        int sum = 0;
        for (; l >= 0; l--) {
            sum += arr[l];
            //和超出target了,将指针向右移动
            while (sum > target) {
                sum -= arr[r];
                r--;
            }
            if (sum == target) {
                //从右向左,在当前位置的子串最小值
                len[l] = min(len[l + 1], r - l + 1);
                //更新最终的两个子数组和,注意len[r + 1]
                ans = min(ans, r - l + 1 + len[r + 1]);               
            } else {
                len[l] = len[l + 1];
            }
        }
        return ans == 2e5 ? -1 : ans;
    }
};

2.Protocol buffer 编码和解码 谷歌 整数变长编码

https://www.cnblogs.com/love-study-chase/p/13443062.html

cpp 复制代码
#include <iostream>
#include <unordered_map>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;

void encode(unsigned int n){
    if(n < 128) {
        if(n < 16) cout <<"0X0"<<hex<<n;
        else cout <<"0X"<<hex<<n;  
        return;
    }
    while(n){
        unsigned int tmp;
        if(n >= 128){
            tmp = (0x80 | (n & 0x7F));
            cout<<"0X"<<setiosflags(ios::uppercase)<<hex<<tmp;//大写16进制数字
        }else{
            tmp = (0x00|(n & 0x7F));
            if(tmp < 16) cout <<"0X0"<<hex<<tmp;
            else cout <<"0X"<<hex<<tmp;
        }
        n >>= 7;
    }
    return;
}
unsigned int decode(string& x){
    unsigned int u, res = 0;
    int cnt = 0;
    while(x.size()){
        string tmp = x.substr(0,4);
      //必须要依据格式输入 否则超索引范围
        x = x.substr(4);
        tmp = tmp.substr(2);
        u = 0;
        for(int i = 0; i < tmp.size(); i++){  
            if(tmp[i] >='0' && tmp[i] <= '9') u = u * 16 + tmp[i] - '0';
            if(tmp[i] >='A' && tmp[i] <= 'F') u = u * 16 + tmp[i] - 'A' + 10;
        }
        unsigned int temp;
        temp = (u & 0x7F);
        for(int i = 1; i <= cnt; i++){  
            temp <<= 7;
        }
        res += temp;
        cnt++;
    }
    return res;
}

int main(){ 
    unsigned int n;
    string x;
    cin >> n >> x;
    encode(n);
    cout <<endl;
    cout <<dec<<decode(x)<<endl; 
    return 0;
}
相关推荐
江畔柳前堤5 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore6 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考8 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面9 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号9 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI10 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者11 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者11 小时前
【征程6】校准量化中HistogramObserver解析
算法