双指针刷题总结

int removeElement(vector<int>& nums, int val) {
        //定义两个指针,一个一直往前走,碰到与目标值不一样的元素就赋值给另一个指针
        //另一个指针如果指的非目标值会直接被覆盖,如果指到了目标值会被前一个指针的非目标值覆盖
        int j=0;//后一个指针
        for(int i=0;i<nums.size();i++){
            if(nums[i]!=val){
                nums[j++]=nums[i];//后指针加一
            }
        }
        return j;
    }

 

 void merge(int A[], int m, int B[], int n) {
        //常规思路是从前往后进行比较添加,但是这里A数组扩容了,只留出了后面
        //所以从后往前添加
        int i=m-1;int j=n-1;
        int k=m+n-1;
        while(i>=0&&j>=0){
            if(A[i]<B[j]){
                A[k--]=B[j--];
            }
            else{//为什么不用if条件呢,这样会比较混乱,希望循环的每一步都只进行清晰的处理
                A[k--]=A[i--];
            }
        }
        //如果A添加完了,说明后面都是B了
        if(i<0){
            for(;j>=0;j--){
                A[k--]=B[j];
            }
        }
    
        
    }

 

string minWindow(string S, string T) {
        // write code here
        int count=0;
        string res=S+'0';
        unordered_map<char,int>hash1;
        unordered_map<char,int>hash2;
        for(int i=0;i<T.size();i++){
            hash1[T[i]]++;
        }
        int i=0;
        for(int j=0;j<S.size();){
            if(hash1.find(S[j])!=hash1.end()){
                hash2[S[j]]++;
                if(hash1[S[j]]==hash2[S[j]]){
                    count++;
                }
            }
            if(count==hash1.size()){
                while(count==hash1.size()){
                    if(j-i+1<res.size()){
                    res=S.substr(i,j-i+1);
                }
                    if(hash1.find(S[i])!=hash1.end()){
                        if(hash1[S[i]]==hash2[S[i]]){
                            count--;
                        }
                        hash2[S[i]]--;
                    }
                    i++;
                }
            }

            j++;
        }
        if(res==S+'0')return "";
        else
        return res;
    }

 

int maxLength(vector<int>& arr) {
        // write code here
        int i=0;int j=0;
        int len=0;
        int res=0;
        unordered_set<int>hash;
        for(;j<arr.size();){
            if(hash.find(arr[j])==hash.end()){
                hash.insert(arr[j]);
                len++;
            }
            else{
                while(hash.find(arr[j])!=hash.end()){
                res=max(res,len);
                hash.erase(hash.find(arr[i]));
                len--;
                i++;
                }
                hash.insert(arr[j]);
                len++;
            }
            j++;
        }
        return res>=len?res:len;
    }

 

int maxArea(vector<int>& height) {
        // write code here
        if (height.size() < 2)
            return 0;
        int res = 0;
        //双指针左右界
        int left = 0;
        int right = height.size() - 1;
        //共同遍历完所有的数组
        while (left < right) {
            //计算区域水容量
            int capacity = min(height[left], height[right]) * (right - left);
            //维护最大值
            res = max(res, capacity);
            //优先舍弃较短的边
            if (height[left] < height[right])
                left++;
            else
                right--;
        }
        return res;

    }

 

class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        for (int i = 0; i < height.size(); i++) {
            // 第一个柱子和最后一个柱子不接雨水
            if (i == 0 || i == height.size() - 1) continue;

            int rHeight = height[i]; // 记录右边柱子的最高高度
            int lHeight = height[i]; // 记录左边柱子的最高高度
            for (int r = i + 1; r < height.size(); r++) {
                if (height[r] > rHeight) rHeight = height[r];
            }
            for (int l = i - 1; l >= 0; l--) {
                if (height[l] > lHeight) lHeight = height[l];
            }
            int h = min(lHeight, rHeight) - height[i];
            if (h > 0) sum += h;
        }
        return sum;
    }
};

 

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() <= 2) return 0;
        vector<int> maxLeft(height.size(), 0);
        vector<int> maxRight(height.size(), 0);
        int size = maxRight.size();

        // 记录每个柱子左边柱子最大高度
        maxLeft[0] = height[0];
        for (int i = 1; i < size; i++) {
            maxLeft[i] = max(height[i], maxLeft[i - 1]);
        }
        // 记录每个柱子右边柱子最大高度
        maxRight[size - 1] = height[size - 1];
        for (int i = size - 2; i >= 0; i--) {
            maxRight[i] = max(height[i], maxRight[i + 1]);
        }
        // 求和
        int sum = 0;
        for (int i = 0; i < size; i++) {
            int count = min(maxLeft[i], maxRight[i]) - height[i];
            if (count > 0) sum += count;
        }
        return sum;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值