Facebook面试题专题5 - leetcode133. Clone Graph/76. Minimum Window Substring - Hard

本文深入解析了两个经典算法问题:图的深拷贝和寻找字符串中的最小窗口子串。首先,介绍了如何使用广度优先搜索和字典来避免循环访问,实现图的深拷贝。其次,探讨了如何在O(n)的时间复杂度内找到包含特定字符集的最小子串,通过双指针技巧和字符计数优化算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

133. Clone Graph

题目描述

给定一个图,返回它的深拷贝。图的每个结点包含一个label和neighbors列表(给定的结点和neighbor间有边连接)。

例子

思想
为了避免循环访问导致死循环,用一个字典dic(集合也可以)记录已被访问过的结点。

解法

# Definition for a undirected graph node
# class UndirectedGraphNode:
#     def __init__(self, x):
#         self.label = x
#         self.neighbors = []

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return None
        
        nodeCloned = UndirectedGraphNode(node.label)
        dic = {node:nodeCloned}    # 记录已访问过的结点
        queue = [node]
        
        while queue:
            cur = queue.pop(0)
            for neigh in cur.neighbors:
                if neigh not in dic:    # 未访问过, 存储到dic中
                    dic[neigh] = UndirectedGraphNode(neigh.label)
                    queue.append(neigh)
                dic[cur].neighbors.append(dic[neigh])
        return nodeCloned
76. Minimum Window Substring - Hard

题目描述

给定字符串S和字符串T,找到S中的最小窗口,包含字符串T中的所有字符。

如果不存在这样的窗口,返回空字符串"";如果存在,题目保证唯一。

例子

Input: S = “ADOBECODEBANC”, T = “ABC”
Output: “BANC”

思想
要求时间复杂度O(n)
初始化左右指针为位置0,并将t中字符计数保存在tDic中。
1)移动右指针,直到包含T中所有字符
2)在cnt == 0的前提下,移动左指针,直到遇到T中的字符
3)左指针右移,以再次补全窗口

注意包含多余t中字符的情况:若t = ‘ABC’,当窗口移动到’DOBECODEB’时,此时tDic[‘B’]+=1,而cnt=1不变;当移动到’DOBECODEBA’时,cnt-=1变为0,而tDic[‘B’] = -1不变。

解法

class Solution(object):
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        tDic = {}
        for c in t:
            tDic[c] = tDic.get(c, 0) + 1
                
        start = 0
        cnt = len(t)
        minLen = float('inf')
        minLenStart = -1
        for i, c in enumerate(s):
            if c in tDic:
                if tDic[c] > 0:    # 在大于0时, 才有cnt-1
                    cnt -= 1
                tDic[c] -= 1
            
            while cnt == 0:
                if minLen > i - start:
                    minLen = i - start
                    minLenStart = start
                if s[start] in tDic:
                    tDic[s[start]] += 1
                    if tDic[s[start]] > 0:    # 在tDic不满足条件时, 才有cnt+1
                        cnt += 1
                start += 1
                
        return '' if minLenStart == -1 else s[minLenStart:minLenStart+minLen+1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值