首页 > 其他分享 >LeetCode —— 子串

LeetCode —— 子串

时间:2023-07-12 21:44:10浏览次数:41  
标签:子串 right 前缀 int 数组 preSum LeetCode left

560. 和为 K 的子数组(哈希表)

官方题解:https://leetcode.cn/problems/subarray-sum-equals-k/solution/he-wei-kde-zi-shu-zu-by-leetcode-solution/

假设 left 到 right 下标的子数组和为 k
nums[left...right] = k
preSum[right] - preSum[left] = k
preSum[left] = preSum[right] - k
所以每次到 right 的时候,找到等于 preSum[right] - k 的 preSum[left] 有多少个
用一个 map 来记录,前缀和的 count (见官方题解动画)
key: 前缀和的值
value: 前缀和为这个值的个数
map 要放入一个初始值 {0,1}

 

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> leftPreSum2CntMap = new HashMap();
        
        leftPreSum2CntMap.put(0, 1);
        int rightPreSum = 0;
        // 总的满足条件的子数组个数的计数,最后的结果
        int count = 0;
        for (int right=0;right<nums.length;right++) {
            rightPreSum += nums[right];
            // [...i]
            // left 到 right 的子数组和为 k
            // nums[left...right] = k
            // preSum[right] - preSum[left] = k
            // preSum[left] = preSum[right] - k
            // 所以每次到 right 的时候,找到等于 preSum[right] - k 的 preSum[left] 有多少个
            Integer leftPreSumCnt = leftPreSum2CntMap.get(rightPreSum - k);
            if (leftPreSumCnt != null) {
                count += leftPreSumCnt;
            }

            // 将这次的和放到 map 里
            Integer rightPreSumCnt = leftPreSum2CntMap.get(rightPreSum);
            if (rightPreSumCnt == null) {
                rightPreSumCnt = 0;
            }
            leftPreSum2CntMap.put(rightPreSum, ++rightPreSumCnt);
        }
        return count;
    }
}

 

标签:子串,right,前缀,int,数组,preSum,LeetCode,left
From: https://www.cnblogs.com/suBlog/p/17548940.html

相关文章

  • Leetcode - 动态规划总结(必看!!!)
     一、labuladong动态规划模板思路wiki:https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/dong-tai-g-1e688/题目: 动态规划模板思路: 二、我自己如何理解【状态】【选择】 以714题目《最佳时机去买卖股票+手续费》为例子:1.确定【状态】--寻找原问题和子问题中,......
  • 5. 最长回文子串
    给你一个字符串s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。>动态规划classSolution{public:stringlongestPalindrome(strings){int......
  • 最长回文子串时间复杂度为O(n)的算法
    给你一个字符串s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb" 提示:1<=s.length<=1000s仅由数字和英文字母组成来源:力扣(LeetCo......
  • LeetCode 剑指 Offer 11. 旋转数组的最小数字
    题目链接:LeetCode剑指Offer11.旋转数组的最小数字题意:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [......
  • LeetCode 剑指 Offer 12. 矩阵中的路径
    题目链接:LeetCode剑指Offer12.矩阵中的路径题意:给定一个 mxn二维字符网格 board和一个字符串单词 word。如果 word存在于网格中,返回true;否则,返回false。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元......
  • LeetCode 234. 回文链表
    classSolution{public:ListNode*reverse(ListNode*head)//翻转以head为头节点的链表{if(!head||!head->next)returnhead;autoa=head,b=head->next;while(b){autoc=b->next;b->next=a;......
  • LeetCode -- 918. 环形子数组的最大和
     遇到环形问题一般有两种考虑方法:1.破环成链2.分为数组中间部分和数组两边部分分别考虑本题采用第二种考虑方法,将原数组分为中间部分和两边部分分别考虑。中间部分即为子数组最大和,两边部分计总和减去中间部分最小和。classSolution{public:intma......
  • LeetCode 热题 100 之 128. 最长连续序列
    题目描述给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为 O(n)的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums......
  • LeetCode -- 826. 安排工作以达到最大收益
     方法一:二分加枚举通过二分快速查找小于某个难度值的最大价值。classSolution{public:intmaxProfitAssignment(vector<int>&difficulty,vector<int>&profit,vector<int>&worker){constintn=(int)difficulty.size();vector<pai......
  • 7-11 leetcode 2612
    请你编写一个异步函数,它接收一个正整数参数 millis ,并休眠这么多毫秒。要求此函数可以解析任何值。 ps:promise期约函数(异步函数)的使用,promise是一个对象 newpromise /***@param{number}millis*/asyncfunctionsleep(millis){//返回一个异步函数......