题解 | #最小覆盖子串#

最小覆盖子串

http://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac

思路:滑动窗口

  • 核心:什么条件下,才更新窗口中的数据。
  • 思考1:当移动右指针right扩大窗口时,到达当前字符,需要做什么事,更新哪些数据,求可行解?
  • 思考2:什么条件下,窗口应该暂停扩大,开始移动left来缩小窗口,求最优解?
  • 思考3:当移动左指针left缩小窗口时,到达当前字符,需要做什么事,更新哪些数据,求最优解?
  • 思考4:需要的最优解应该在扩大窗口时更新,还是在缩小窗口时更新?
  • 如果一个字符进入窗口,应该增加 window 计数器;如果一个字符将移出窗口的时候,应该减少 window 计数器;当 valid 满足 need 时应该收缩窗口;应该在收缩窗口的时候更新最终结果。
import java.util.*;


public class Solution {
    /**
     *
     * @param S string字符串
     * @param T string字符串
     * @return string字符串
     */
    public String minWindow (String S, String T) {
        // write code here
        HashMap<Character, Integer> need = new HashMap<>();
        HashMap<Character, Integer> window = new HashMap<>();
        for (int i = 0; i < T.length(); ++i) {
            char ch = T.charAt(i);
            need.put(ch, need.getOrDefault(ch, 0) + 1);
        }
        int left = 0, right = 0; // 左闭右开的窗口
        int valid = 0;
        // 记录最小覆盖子串的开始索引和长度
        int start = 0, len = Integer.MAX_VALUE;
        while (right < S.length()) {
            char c = S.charAt(right);
            // 当右指针到达某个字符时要做的事
            if (need.containsKey(c)) { // 目标字符串包含该字符串时,才更新窗口
                window.put(c, window.getOrDefault(c, 0) + 1);
                if (window.get(c).equals(need.get(c))) { // 窗口中的当前字符c已经满足需求
                    valid++;
                }
            }
            ++right; // 扩大窗口

            while (valid == need.size()) { // 找到第一个满足need的位置,窗口停止扩大
                // 计算窗口起点和长度
                if (right - left < len) {
                    start = left;
                    len = right - left;
                }
                // 左指针到达某个字符时需要做的事
                char d = S.charAt(left);
                if (window.containsKey(
                            d)) { // 窗口中包含当前字符d,需要更新窗口
                    if (window.get(d).equals(need.get(d))) { // 数目匹配
                        valid--;
                    }
                    window.put(d, window.get(d) - 1);
                }
                ++left;  // 缩小窗口
            }
        }

        //System.out.println("left: " + left + ", right: " + right);
        StringBuilder res = new StringBuilder();
        if (len != Integer.MAX_VALUE) {
            for (int i = start; i < start + len; i++) {
                res.append(S.charAt(i));
            }
        }
        return new String(res);
        // return len == Integer.MAX_VALUE ? "" : S.substring(start, start + len);
    }
}
全部评论

相关推荐

头像
昨天 15:11
已编辑
华东师范大学 算法工程师
暑期实习从2月开始投,面了两个月,流程该挂的都挂完了,腾讯字节一共号称是1.7w个hc,不知道都发给谁了,估计今年秋招要难顶。Timeline米哈游、美团、蚂蚁、微软等公司直接简历挂穿,没进面。携程:3.3&nbsp;投递、测评3.12&nbsp;笔试3.18&nbsp;一面3.25&nbsp;二面4.13&nbsp;ai面(hr面)4.14&nbsp;英语测评4.23&nbsp;offer(已拒)腾讯:2.6&nbsp;测评2.28&nbsp;wxg一面3.5&nbsp;wxg二面(挂)3.11&nbsp;teg一面3.21&nbsp;teg二面(取消)3.31&nbsp;teg一面4.10&nbsp;teg二面(挂)4.21&nbsp;wxg一面4.24&nbsp;wxg二面(挂)字节:1.28&nbsp;aml约面(取消)3.17&nbsp;火山一面(挂)4.8&nbsp;aml一面(挂)4.20&nbsp;抖音data一面(挂)阿里:3.23&nbsp;投递、测评3.28&nbsp;笔试3.31&nbsp;淘天一面4.8&nbsp;钉钉一面4.9&nbsp;淘天二面4.10&nbsp;阿里控股一面4.12&nbsp;钉钉二面(取消)4.15&nbsp;淘天hr面4.16&nbsp;淘天offer(已接)4.21&nbsp;高德一面(取消)4.22&nbsp;淘宝闪购一面(取消)面试最大的感触是,现在撞上ai转型,一堆老业务急着转向,新业务非常不成熟,研究型的组bar非常高根本进不去,业务侧挂着算法的岗位干的都是工程活,面试却又要问算法,另外agent的落地也远没有那么广,绝大多数还是那套写死的系统调一下llm&nbsp;api或者做做rag,其余少部分真的在搭agent的,基本不能在线上服务用什么很智能的模型,现阶段成本太高,进去大概率就是给垃圾模型从工程方面兜底,除了业务场景的应用和数据经验以外,技术方面很难有什么提升。算法岗做不了基模的还是去搜广推好,之前判断失误了完全没投,秋招不知道还进不进得去。
绿糖滑稽:携程这什么雷霆流程时长
我的求职进度条
点赞 评论 收藏
分享
03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务