IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 专题复习:双指针(1) 滑动窗口(前提是:有序数组) -> 正文阅读

[数据结构与算法]专题复习:双指针(1) 滑动窗口(前提是:有序数组)

leetcode?1423. 可获得的最大点数

?

思路:由于必须包含数组的首元素或者尾部元素。可以采用在数组的两端来滑动。

1423.gif

?代码如下,首先,sum为数组中前k个元素之和,然后,窗右边往左划,tempsum - 出窗的元素,窗左边往左滑,到数组的末尾,tempSum + 进窗的元素,一直到窗中不包含首位元素或者末尾元素。

class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int sum = 0;
        int size = cardPoints.size();
        for(int i = 0; i < k; i++)
        {
            sum += cardPoints[i];
        }
        int tempSum = sum;
        for(int i = k - 1; i >= 0; i--)
        {
            tempSum -= cardPoints[i];
            tempSum += cardPoints[size - (k - i)];
            sum = max(sum, tempSum);
        }
        return sum;

    }
};

leetcode26. 删除有序数组中的重复项

注意:不要使用额外的数组空间,你必须在?原地?修改输入数组?并在使用 O(1) 额外空间的条件下完成

思路:将数组中出现的元素按顺序放在数组的首部,效果如下:

原数组 nums = [0,0,1,1,1,2,2,3,3,4]

效果后:nums =[0,1,2,3,4,2,2,3,3,4]?

双指针:left = 0, right = 1,如果nums[right] != nums[left]? ? { left++; nums[left] = nums[right];}

如果?nums[right] == nums[left]? right++; 最后,return left+1;

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int size = nums.size();
        if(size == 0) return 0;
        int left = 0, right = 1;
        for(right = 1; right < size; right++)
        {
            if(nums[right] != nums[left])
            {
                nums[++left] = nums[right];
            }
        }
        return left+1;
        
    }
};

剑指 Offer 57 - II. 和为s的连续正数序列

利用滑窗, left和right 表示连续数组的范围

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        if(target == 1) return {{1}};
        vector<vector<int>> res;
        if(target == 2) return res;
        int left = 1, right = 2;
        int sum = left + right;
        while(left <= target/2)
        {
            if(sum == target)
            {
                vector<int> temp;
                for(int i = left; i <= right; i++) 
                {
                    temp.push_back(i);
                }
                res.push_back(temp);
            }
            if(sum >= target)
            {
                sum -= left;
                left++;
            }
            else
            {
                right++;
                sum += right;
            }
        }
        return res;

    }
};

leetcode?349. 两个数组的交集

跟下一题一致,只不过 做了去重复操作

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        int size1 = nums1.size(), size2 = nums2.size();
        vector<int> res;
        if(size1 == 0 || size2 == 0)  return res;
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        int left = 0, right = 0;
        while(left < size1 && right < size2)
        {
            if(nums1[left] < nums2[right]) left++;
            else if(nums1[left] > nums2[right]) right++;
            else
            {
                res.push_back(nums1[left]);
                left++;
                while(left < size1 && nums1[left] == nums1[left-1]) left++;
                right++;
                while(right < size2 && nums2[right] == nums2[right-1]) right++;
            }
        }
        return res;
    }
};

leetcode350. 两个数组的交集 II

首先,将两个数组排序,然后,利用双指针,分别遍历两个数组。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        vector<int> res;
        int size1 = nums1.size();
        int size2 = nums2.size();
        if(size1 == 0 || size2 == 0) return res;
        int i = 0, j =0;//用i作为索引遍历nums1 用j作为索引遍历nums2
        while(i < size1 && j < size2)
        {
            if(nums1[i] > nums2[j]) j++;
            else if(nums1[i] < nums2[j]) i++;
            else
            {
                res.push_back(nums1[i]);
                i++;
                j++;
            }
        }
        return res;
    }
};

?leetcode?424. 替换后的最长重复字符

比较难想到,利用map记录出现次数最多的字符及次数

class Solution {
public:
    int characterReplacement(string s, int k) {
        int size = s.length();
        if(size <= 1) return size;

        unordered_map<char ,int> a;
        int maxSameCount = 0;
        int maxWindow = 0;
        int left = 0, right = 1;
        a[s[left]]++;
        for(;right < size; right++)
        {
            a[s[right]]++;
            maxSameCount = max(maxSameCount, a[s[right]]);
            if(maxSameCount + k < right - left + 1)
            {
                a[s[left]]--;
                left++;
            }
            else
            {
                maxWindow = max(maxWindow, right -left + 1);
            }
        }
        return maxWindow;

    }
};

leetcode125. 验证回文串

大写字符转换为小写字符 调用函数tolower? ?小写字符转换为大写字符 调用函数toupper

class Solution {
    bool isValid(char a)
    {
        if( a >='0'&& a <= '9' || a >= 'a'&& a <= 'z' || a >= 'A'&&a <= 'Z' )
        {
            return true;
        }
        return false;
    }
public:
    bool isPalindrome(string s) {
        int len = s.length();
        if(len <= 1) return true;

        int left = 0; int right = len - 1;
        while(left <= right)
        {
            if( isValid(s[left]) && isValid(s[right]))
            {

                if( tolower(s[left]) == tolower(s[right]))
                {
                    left++;
                    right--;
                }
                else
                {
                    return false;
                }
            }
            else if(!isValid(s[left]) && isValid(s[right])) left++;
            else if(isValid(s[left]) && !isValid(s[right])) right--;
            else
            {
                left++;
                right--;
            }
        }
        return true;
    }
};

leetcode109. 有序链表转换二叉搜索树

思路:将链表从中间分隔成两段,然后利用递归

利用快慢指针,找到链表中间节点

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        if(!head) return nullptr;
        if(!head->next) return new TreeNode(head->val);
        ListNode* slow = head, *fast = head, *pre = nullptr;
        //这里通过快慢指针找到链表的中间结点slow,pre就是中间
       //结点slow的前一个结点
        while(fast && fast->next)
        {
            pre = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        pre->next = nullptr;//将链表分隔为两部分
        //slow是链表的中间节点
        TreeNode* root = new TreeNode(slow->val);
        root->left = sortedListToBST(head);
        root->right = sortedListToBST(slow->next);
        return root;
    }
};

leetcode61. 旋转链表

思路:先把链表整成环, 另外,由于k可能大于链表的长度,因此有必要计算出链表的长度。

当k > len时,即相当于往右移动k%len个位置。最后,需要将之前的环形链表截断。

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(!head) return head;
        ListNode *fast = head, *slow = head;
        int len = 1;
        //计算链表的长度
        while(fast->next)
        {
            len++;
            fast = fast->next;
        }
        fast->next = head;//将链表构成环

        //还需要将环形链表截断
        int step = k%len; //当k大于len时,实际上相当于向右移动k%len个位置
        //向右移step个位置,即需要在链表的第len - step个节点之前截断,因此,需要找到
        // 第len - step - 1个节点
        int k1 = len - step - 1;
        while((k1--)>0)
        {
            slow = slow->next;
        }
        ListNode *newHead = slow->next;
        slow->next =nullptr;
        return newHead;
    }
};

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

思路:利用set set.insert(3)? ?erase(3)? ? ?set.find(3) != set.end()

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.length();
        if(len <= 1) return len;
        int maxLen = 0;
        set<char> a;
        int left = 0;
        a.insert(s[left]);
        for(int i = 1; i < len; i++)
        {
            while(a.find(s[i]) != a.end())
            {
                a.erase(s[left]);
                left++;
            }
            a.insert(s[i]);
            maxLen= max(maxLen, i - left + 1);
        }
        return maxLen;
    }
};

方法二:直接利用数组m 记录一个字母如果后面出现重复时,left 应该调整到的新位置

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> m(128,0);//m 记录一个字母如果后面出现重复时,left 应该调整到的新位置
        int left = 0;
        int maxLen = 0;
        for(int right = 0; right < s.length();right++)
        {
            if(m[s[right]] > 0)
            {
                left = max(left, m[s[right]]);//注意,此时要取最大的left 
                                              //比如"abba" 当取到第二个a时,此时的left是为2 不应该是 m[a]即1
            }
            m[s[right]] = right + 1; 
            maxLen = max(maxLen, right - left + 1);
        }
        return maxLen;
    }
};

leetcode11:?11. 盛最多水的容器

左指针left为0 右指针left为len -1

遍历方式:nums[left] < nums[right] left++; 否则,right++

class Solution {
public:
    int maxArea(vector<int>& height) {
        int len = height.size();
        int left = 0, right = len - 1;
        int maxArea = 0;
        while(left < right)
        {
            int areaTemp = (right - left)*min(height[right] , height[left]);
            maxArea = max(maxArea, areaTemp);
            if(height[left] < height[right]) left++;
            else right--;
        }
        return maxArea;
    }
};

??

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 12:18:24  更:2021-07-26 12:18:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:57:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码