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 + len[r + 1] 中的较小值。这里 len[r + 1] 表示从 r + 1到数组末尾的子数组的最小长度。因为我们想找到两个不相交的子数组,所以加上从 r + 1 开始的子数组的最小长度是合理的。
  • 更新len[l] 为 curlen 和 len[l + 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;
}
相关推荐
一直学习永不止步3 分钟前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
小刘|34 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou39 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
van叶~1 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
简简单单做算法1 小时前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
云卓SKYDROID1 小时前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
半盏茶香2 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童2 小时前
双指针算法习题解答
算法
想要打 Acm 的小周同学呀2 小时前
LRU缓存算法
java·算法·缓存
阑梦清川2 小时前
在鱼皮的模拟面试里面学习有感
学习·面试·职场和发展