hot100子串(1)

第一题:560. 和为 K 的子数组 - 力扣(LeetCode)

为什么不能用滑动窗口?举个例子:nums=[1,2,3,-2] ,k=4.left为1,right为3时,发现窗口内的值已经比4要大,所以left右移。但漏掉了1+2+3+(-2)=4这一组。因为负值的存在,无法判断究竟是要扩大窗口,还是滑动到下一个窗口。

考虑用前缀和。对于一个起始位置为j,终止位置为i的子串,其元素和为pre[i]-pre[j-1].如果pre[i]-pre[j-1]==k,那么这个子串是符合题意的。移项可得:pre[j-1]=pre[i]-k.我们遍历一次nums可以得到每个位置的前缀和,那么不妨在得到pre[i]的同时,看是否存在前缀和为pre[i]-k的子串,如果存在就将答案增加相应的个数.考虑用unordered_map,因为我们要找“是否存在前缀和为pre[i]-k的子串”,所以key为前缀和,value为这样的子串的个数。

需要注意的是mp[0]=1,因为如果pre恰好为k,那么pre-k=0,这样的子串是存在的。

class Solution
{
public:
    int subarraySum(vector<int>& nums, int k)
    {
        unordered_map<int, int>mp;//键:前缀和,值:出现次数
        int pre = 0, cnt = 0;
        mp[0] = 1;
        for (int x : nums)
        {
            pre += x;
            if (mp.contains(pre - k))
            {
                cnt += mp[pre - k];
            }
            mp[pre]++;
        }
        return cnt;
    }
};

### LeetCode Hot 100 Problems 列表 以下是基于社区讨论和高频面试题目总结的 LeetCode 热门前 100 题列表。这些题目涵盖了数组、链表、哈希表、动态规划等多个领域,适合准备技术面试的人群。 #### 数据结构分类 - **数组** - 寻找最长连续序列 (Longest Consecutive Sequence)[^2] - 字符串中的所有字母异位词 (Find All Anagrams in a String)[^2] - **链表** - 环形链表 II (Linked List Cycle II)[^1] - **栈与队列** - 实现最小栈 (Min Stack) - 滑动窗口最大值 (Sliding Window Maximum) - **树** - 二叉树的最大路径和 (Binary Tree Maximum Path Sum) - 序列化与反序列化二叉树 (Serialize and Deserialize Binary Tree) - **图** - 岛屿数量 (Number of Islands) - 克隆图 (Clone Graph) - **字符串** - 正则表达式匹配 (Regular Expression Matching)[^3] - 最长回文子串 (Longest Palindromic Substring) - **动态规划** - 不同路径 (Unique Paths) - 跳跃游戏 (Jump Game) - **其他** - LRU 缓存机制 (LRU Cache) --- #### 示例代码片段 以下是一些经典问题的实现示例: ##### Longest Consecutive Sequence ```python class Solution: def longestConsecutive(self, nums: List[int]) -> int: longest_streak = 0 num_set = set(nums) for num in num_set: if num - 1 not in num_set: current_num = num current_streak = 1 while current_num + 1 in num_set: current_num += 1 current_streak += 1 longest_streak = max(longest_streak, current_streak) return longest_streak ``` ##### Linked List Cycle II ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class Solution: def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next if slow == fast: break else: return None pointer = head while pointer != slow: pointer = pointer.next slow = slow.next return pointer ``` ##### Regular Expression Matching ```cpp bool isMatch(string s, string p) { int m = s.size(), n = p.size(); vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false)); dp[0][0] = true; for(int j = 2; j <= n; ++j){ if(p[j - 1] == '*') dp[0][j] = dp[0][j - 2]; } for(int i = 1; i <= m; ++i){ for(int j = 1; j <= n; ++j){ if(s[i - 1] == p[j - 1] || p[j - 1] == '.') dp[i][j] = dp[i - 1][j - 1]; else if(p[j - 1] == '*'){ dp[i][j] = dp[i][j - 2]; // * counts as zero if(p[j - 2] == '.' || p[j - 2] == s[i - 1]){ dp[i][j] |= dp[i - 1][j]; // * counts as one or more } } } } return dp[m][n]; } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值