美文网首页
2020-3-3 刷题记录

2020-3-3 刷题记录

作者: madao756 | 来源:发表于2020-03-03 23:59 被阅读0次

    0X00 leetcode 刷题 5 道

    0X01 每道题的小小总结

    面试题 10.01. Sorted Merge LCCI

    热身题,一个简单的合并两个 array 的问题,一开始被 inplace 限制住了,,,,没想到可以先创建一个然后再复制....太傻了

    class Solution:
        def merge(self, A: List[int], m: int, B: List[int], n: int) -> None:
            """
            Do not return anything, modify A in-place instead.
            """
            if len(A) == 0 or len(B) == 0: return
            # 好吧 被 inplace 这个东西限制住了
            # 其实这个题目不难
            # 最后想象边界情况
            pa, pb = 0, 0
            m, n = len(A) - len(B), len(B)
            temp = [0] * (m+n)
            count = 0
            while pa < m or pb < n:
                if pb == n:
                    temp[count] = A[pa]
                    pa += 1
                elif pa == m:
                    temp[count] = B[pb]
                    pb += 1
                elif A[pa] <= B[pb]:
                    temp[count] = A[pa]
                    pa += 1
                else:
                    temp[count] = B[pb]
                    pb += 1                
                count += 1
            A[:] = temp
    

    时间空间复杂度:

    O(N)/O(N)

    425. Word Squares

    dfs + trie 树优化 这是一个很重要的考点,必须记住

    这道题还有个坑,坑在边界条件,其实我注意到了,但是后面忘了...

    就是长度为 1 的情况

    class Solution:
        def find(self, prefix, cur, node):
            if len(prefix) != 0:
                if prefix[0] not in node: return
                self.find(prefix[1:], cur, node[prefix[0]])
            else:
                if '#' in node:
                    cur.append(node['#'])
                for k, v in node.items():
                    if k == '#': continue
                    self.find("", cur, v)
    
        def wordSquares(self, words: List[str]) -> List[List[str]]:
            if len(words) == 0: return None
    
            # 建立 trie
            self.trie = {}
            for w in words:
                p = self.trie
                for c in w:
                    p = p.setdefault(c, {})
                p['#'] = w
    
            # print(self.trie)
    
            def dfs(cur, prefix):
                condidates = []
                self.find(prefix, condidates, self.trie)
                # print("condidates ", condidates)
                prefixIdx = len(prefix) + 1
                for c in condidates:
                    cur.append(c)
                    # print("caonima ", cur)
                    if len(cur) == m:
                        ans.append(cur[:])
                    else:
                        prefix = ""
                        for w in cur:
                            prefix += w[prefixIdx]
                        # print("prefix ", prefix)
                        dfs(cur, prefix)
                    
                    cur.pop()    
                
    
            
            m = len(words[0])
            ans = []
            if m == 1:
                return words
            for w in words:
                dfs([w], w[1])
            
            return ans
    

    421. Maximum XOR of Two Numbers in an Array

    这个题目感觉挺难的,也并没有 trie 去做,具体用了两个性质

    • 贪心
    • a ^ b = c => b ^ c = a => a ^ c = b

    思路我说一下:

    • 我们假设一个最大值,看这个最大值能不能存在

    利用贪心的思想,我就依次检查最高位能不能为 1 比如第一次(假设只有 4 位)

    1000
    

    我要看其他的数字能不能 ^ 出 1000 不需要两两 ^ .只需要

    将所有数字 mask (只保留第 1 位)以后放入一个 set 里面

    c = 1000 ^ a

    如果 c 也在这个 set 里面那么,就能构成反之不行,

    具体操作看代码:

    class Solution:
        def findMaximumXOR(self, nums: List[int]) -> int:
            # 这个题目有点难度
            # 首先复习两个位运算
            # | 用来给某些位添加
            # & 用来保留某些位其他置 0 用作 mask
            res, mask = 0, 0
            for i in range(31, -1, -1):
                mask |= 1 << i
                s = set()
                for n in nums:
                    s.add(n & mask)
                
                # 计算当前最大值
                temp = res | (1 << i)
    
                for t in s:
                    if t ^ temp in s:
                        res = temp
                        break
                
            return res
    

    时间空间复杂度:

    O(32N)/O(1)

    5. Longest Palindromic Substring

    动态规划,「区间型动态规划」转移方程 见代码注释

    class Solution:
        def longestPalindrome(self, s: str) -> str:
            # 区间型动态规划
            # 长度是关键
            # f(x, y)  的意思是 s[x:y+1] 是不是回文
            # f(x, y) = f(x+1, y-1) and s[x] = s[y]
            if s == "": return s
            m = n = len(s)
            dp = [[False] * n for _ in range(m)]
    
            # init 
            # len1
            for i in range(m):
                dp[i][i] = True
            
            ans = 1
            idx1, idx2 = 0, 0
            # len2
            for i in range(m-1):
                dp[i][i+1] = s[i] == s[i+1]
                if dp[i][i+1]:
                    idx1, idx2 = i, i+1
                    ans = 2
            
            for l in range(3, m+1):
                for x in range(m - l + 1):
                    y = x + l - 1
                    dp[x][y] = dp[x+1][y-1] and s[x] == s[y]
                    if dp[x][y] and l > ans:
                        idx1, idx2 = x, y
                        ans = l
                        
            return s[idx1:idx2+1]
    

    O(n^2)/O(n^2)

    336. Palindrome Pairs

    这个题目我感觉也非常难

    重点还是理解大神代码里面的骚操作:

    class Solution:
        def palindromePairs(self, words: List[str]) -> List[List[int]]:
            # 回文必想空字符
            rev = {}
            # 本身就是回文
            palIdx = []
            for idx, w in enumerate(words):
                t = w[::-1]
                rev[t] = idx
                if t == w: palIdx.append(idx)
            res = []
            for idx, w in enumerate(words):
                # 判断是不是空字符串
                if w:
                    # 这里不需要 + 1 因为 0
                    for i in range(len(w)):
                        left, right = w[:i], w[i:]
                        # 判断是不是左边的
                        if left in rev and right[::-1] == right and rev[left] != idx:
                            res.append([idx, rev[left]])
                        # 同理
                        if right in rev and left == left[::-1] and rev[right] != idx:                  
                            res.append([rev[right], idx])
                else:
                    # 空字符串的其中一部分已经在之前考虑过了
                    # 只需要 考虑 ("", 回文)
                    for loc in palIdx:
                        if loc == idx: continue
                        res.append([idx, loc])
                    
    
    
            return res
    

    复杂度应该是 O(nk^2) / O(n)

    相关文章

      网友评论

          本文标题:2020-3-3 刷题记录

          本文链接:https://www.haomeiwen.com/subject/bkxdlhtx.html