• MS leetcode 题目


    # 717 1比特与2比特字符:判断末尾符号是哪一种

    思路:线性从前向后遍历,维护一个映射list。

    class Solution:
        def isOneBitCharacter(self, bits: List[int]) -> bool:
            if len(bits)==1:
                return True
            else:
                mapList=[]
                while len(bits)>0:
                    if bits[0]==1:
                        mapList.append('F')
                        bits.pop(0)
                        bits.pop(0)
                    else:
                        mapList.append('T')
                        bits.pop(0)
                if mapList[-1]=='T':
                    return True
                else:
                    return False
    View Code

    # 67 二进制求和:二进制加法

    思路:首先处理字符串长度不一致的问题,为较短的字符串前面添0,将两个字符串补齐。然后从后往前加即可,当前位置上的两个数+进位。

    class Solution:
    
        def addZero(self,a,b):
            diff=abs(len(b)-len(a))
            if len(a)<len(b):
                a='0'*diff+a
            elif len(a)>len(b):
                b = '0' * diff + b
            return a,b
    
        def addBinary(self, a: str, b: str) -> str:
                result=''
                a,b=self.addZero(a,b)
                flag=0 # 进位
                for i in range(len(a)):
                    tmp=int(a[len(a)-i-1])+int(b[len(b)-i-1])+flag
                    if tmp==2:
                        flag=1
                        result+='0'
                    elif tmp==3:
                        flag = 1
                        result += '1'
                    else:
                        flag=0
                        result += str(tmp)
                if flag==1:
                    result += '1'
                back=''.join(list(reversed(result)))
                return back
    View Code

     # 415: 67的升级版, replace if-else with //(整除) and %(取余)

    class Solution:
        def addZero(self,a,b):
            diff=abs(len(b)-len(a))
            if len(a)<len(b):
                a='0'*diff+a
            elif len(a)>len(b):
                b = '0' * diff + b
            return a,b
    
        def addStrings(self, num1: str, num2: str) -> str:
            result=''
            a,b=self.addZero(num1,num2)
            flag=0 # 进位
            for i in range(len(a)):
                tmp=int(a[len(a)-i-1])+int(b[len(b)-i-1])+flag
                result+=str(tmp%10) # 10进制数
                flag=tmp//10 
            if flag!=0: #由于题目要求字符串前面不能有0,所以只有非0才添加
                result += str(flag)
            back=''.join(list(reversed(result)))
            return back
    View Code

     ### 从这道题开始,我就不按照LC官网类的方式记录了,直接贴函数代码>>_<<

    # 107: DFS+维护一个以深度为key的字典, value是一个list, 在DFS时依次append, 最后按照key从大到小返回对应value(主要难点在于DFS的实现,DFS的实现方式主要有两种,一种是递归,一种是栈,这里采用递归的实现方式)

    # Definition for a binary tree node.
    class TreeNode:
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    
    def DFS(root,depth,depthDict):
        if root!=None:
            if depth not in depthDict.keys():
                depthDict[depth]=[]
                depthDict[depth].append(root.val)
            else:
                depthDict[depth].append(root.val)
            DFS(root.left,depth+1,depthDict)
            DFS(root.right, depth+1, depthDict)
        else:
            return
    
    def levelOrderBottom(root): # root: TreeNode
        res=[]
        depthDict={}
        depth=0
        DFS(root,depth,depthDict)
        keysSort=list(reversed(sorted(list(depthDict.keys()))))
        for i in keysSort:
            res.append(depthDict[i])
        return res
    
    # Test sample
    rr=TreeNode(3)
    rr.left=TreeNode(9)
    rr.right=TreeNode(20)
    rr.right.left=TreeNode(15)
    rr.right.right=TreeNode(7)
    print(levelOrderBottom(rr))
    View Code

     # 257: DFS (这两道二叉树的题目做起来都有点困难,可能因为对递归理解还不是非常透彻,这里关键在于递归的过程中path会被自动维护)

    # Use the definition for a binary tree node in 107.
    def binaryTreePaths(root): # List[str]
        Paths=[]
        Path=''
    
        def DFS_257(root, path):
            if root != None:
                if path == '':
                    path += str(root.val)
                else:
                    path += ('->' + str(root.val))
                if root.left==None and root.right==None:
                    Paths.append(path)
                DFS_257(root.left, path)
                DFS_257(root.right, path)
            else:
                return
    
        DFS_257(root,Path)
        return Paths
    
    # Test sample
    # rr=TreeNode(3)
    # rr.left=TreeNode(9)
    # rr.right=TreeNode(20)
    # rr.right.left=TreeNode(15)
    # rr.right.right=TreeNode(7)
    # print(binaryTreePaths(rr))
    View Code

     这里补充一下递归分析:

     # 70: DP (乍一看以为这道题就是求二叉树的路径条数,以为可以使用DFS,然递归DFS超时==), 用DP的话首先需要写出通项公式,这里假设f(x)是爬x阶楼梯的方案数,而最后一步可以走1步或者2步,我们可以得到f(x)=f(x-1)+f(x-2),这个比较难想,竟然是斐波那契数。

    def climbStairs(n): # DP
        l=0
        r=1
        sum=0
        for i in range(n):
            sum=l+r
            l=r
            r=sum
        return r
    View Code

    (有关通项的理解后续再补充)

     # 30: 外观数列, 这道题的解法写的比较任意,就是线性扫描+集合判断,更加规范的应该用双指针。

    线性扫描+集合

    def count(num):
        str_num=str(num)
        descriptor=''
        filter_set=[]
        for i in str_num:
            filter_set.append(i)
            if len(set(filter_set))==2:
                descriptor+=(str(len(filter_set[:-1]))+filter_set[-2])
                filter_set = [filter_set[-1]]
            else:
                continue
        descriptor+=(str(len(filter_set))+str(filter_set[-1]))
        return int(descriptor)
    
    def countAndSay(n):
        res=1
        for i in range(n-1):
            res=count(res)
        return str(res)
    
    print(countAndSay(5))
    View Code

     # 204 数质数,该题用常规方法去判断会超时,尝试加了很多trick还是会超时,最后参考了其他人的题解,采用了埃氏筛的方法,主要是对该方法的理解(算法实现)。

    def countPrimes(n): # 埃氏筛
        isPrime=[1]*n # 初始化很重要
        cnt=0
        for i in range(2,n):
            if isPrime[i]:
                cnt+=1
            for j in range(i*i,n,i):
                isPrime[j]=0
        return cnt
    View Code

     # 706 自己实现一个hash表,也就是python中的字典。解决两个问题,第一,哈希函数,第二,哈希碰撞。1,采用取模长%len;2,用一个数组把映射在同一位置的元素装起来,所以是两个数组的嵌套。(这里将第一个数组的长度设置为2069,参考解答的设置,any质数都可以,减小碰撞概率而已)

    class MyHashMap:
    
        def __init__(self):
            self.map=[[]]*2069 # 2069 as a prime
    
        def put(self, key: int, value: int) -> None:
            index=key%2069
            for lst in self.map[index]:
                if lst[0]==key:
                    lst[1]=value
                    return None
            self.map[index].append([key,value])
    
        def get(self, key: int) -> int:
            index=key%2069
            for lst in self.map[index]:
                if lst[0]==key:
                    return lst[1]
            return -1
    
        def remove(self, key: int) -> None:
            index = key % 2069
            for i in range(len(self.map[index])):
                if self.map[index][i][0] == key:
                    del self.map[index][i]
                    break # 要加break,不然会有错,因为这种for iterator删除当前元素继续访问会造成冲突
    View Code

     # 509 斐波那契数(70题的本质)

    def fib(n):
        if n==0:
            return 0
        else:
            l = 0
            r = 1
            sum = 0
            for i in range(n - 1):
                sum = l + r
                l = r
                r = sum
            return r
    View Code

    # 724 找中心索引使得左右两边和相等, 题目也比较好理解,我直接用了sum函数判断,发现两个有意思的点: sum([])=0 ; list[:0]=[] list[len(list):]=[] 第二个点说明切片不会造成越界问题,比如这样:

    def pivotIndex(nums):
        for i in range(len(nums)):
            if sum(nums[:i])==sum(nums[(i+1):]):
                return i
        return -1
    View Code

     # 387 字符串中的唯一字符,该题目比较简单,不多分析,就用字典存储频数即可。

    def firstUniqChar(s):
        uniqueCharList=[]
        times={}
        for i in s:
            if i not in uniqueCharList:
                uniqueCharList.append(i)
                times[i]=1
            else:
                times[i]+=1
        print(uniqueCharList)
        print(times)
        for key in times.keys():
            if times[key]==1:
                return s.index(key)
        return -1
    View Code

    # 198: 数组中不相邻元素的最大和,使用动态规划,经典步骤,建立函数关系f(x),写出子结构表达式。本题目分析如下 (代码部分参考精选题解):

    def rob(nums):
        if len(nums)==0:
            return 0
        elif len(nums)==1:
            return nums[0]
        else:
            N=len(nums)
            dp=[0]*(N+1)
            dp[0]=0
            dp[1]=nums[0]
            for i in range(2,N+1):
                dp[i]=max(dp[i-1],dp[i-2]+nums[i-1])
            return dp[N]
    View Code

     # 232 用两个栈模拟队列,一个栈作为输入栈,一个栈作为输出栈,push的时候都加入输入栈,pop从输出栈弹出,此时如果为空就需要将输入栈的全部弹出到输出栈再输出。(相当于将一个队列拆成了两部分,入栈和出栈)

    这个video很清晰==

    class MyQueue:
    
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.inputStack=[]
            self.outputStack=[]
    
    
        def push(self, x: int) -> None:
            """
            Push element x to the back of queue.
            """
            self.inputStack.append(x)
    
    
        def pop(self) -> int:
            """
            Removes the element from in front of queue and returns that element.
            """
            if len(self.outputStack)!=0:
                value=self.outputStack.pop()
                return value
            else:
                for i in range(len(self.inputStack)):
                    self.outputStack.append(self.inputStack.pop())
                value = self.outputStack.pop()
                return value
    
    
        def peek(self) -> int:
            """
            Get the front element.
            """
            if len(self.outputStack)!=0:
                value=self.outputStack[-1]
                return value
            else:
                for i in range(len(self.inputStack)):
                    self.outputStack.append(self.inputStack.pop())
                value = self.outputStack[-1]
                return value
    
    
        def empty(self) -> bool:
            """
            Returns whether the queue is empty.
            """
            if len(self.inputStack)==0 and len(self.outputStack)==0:
                return True
            else:
                return False
    View Code

     # 225 用两个队列模拟栈:核心思想就是将一个队列辅以某些操作直接变成栈的存储结构(元素取反存储)。实现:一个队列+一个tmp队列

    class MyStack:
    
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.Q=[]
            self.Q_tmp=[]
    
        def push(self, x: int) -> None:
            """
            Push element x onto stack.
            """
            self.Q_tmp=[]
            self.Q_tmp.append(x)
            if len(self.Q)!=0:
                for i in range(len(self.Q)):
                    self.Q_tmp.append(self.Q[i])
            self.Q=self.Q_tmp
    
        def pop(self) -> int:
            """
            Removes the element on top of the stack and returns that element.
            """
            res=self.Q[0]
            self.Q=self.Q[1:]
            return res
    
        def top(self) -> int:
            """
            Get the top element.
            """
            return self.Q[0]
    
        def empty(self) -> bool:
            """
            Returns whether the stack is empty.
            """
            if len(self.Q)==0:
                return True
            else:
                return False
    View Code

     # 28 查找子字符串出现的位置

    def strStr(haystack, needle):
        if needle=='' or needle==haystack:
            return 0
        elif len(needle)>len(haystack):
            return -1
        else: # needle 长度小于hay
            for i in range(len(haystack)):
                if i+len(needle)<=len(haystack):
                    if haystack[i:i+len(needle)]==needle:
                        return i
                    else:
                        if i + len(needle) == len(haystack): # 考虑最后一次不匹配的情况
                            return -1
                        continue
                else:
                    return -1
    View Code

    写的太复杂了==按照相同的思路可以用一行代码实现(for start in range(n - L + 1):)or 还可以采用基于hash的方法,将字符串映射到hash,如Rabin Karp

     # 349 两个数组的交集(就遍历...)

    def intersection(nums1, nums2):
        intersect=[]
        for i in nums1:
            if (i in nums2) and (i not in intersect):
                intersect.append(i)
        return intersect
    View Code

    # 784 字母大小写全排列。这个题目关键是抓住全排列和二进制数之间的关系。

    def letterCasePermutation(S):
        L=[]
        letterIndex=[]
        idx=-1
        str=S # store numbers in S and reserve space for character
        for i in S: # 数字
            idx+=1
            if i>='0' and i<='9':
                L.append(i)
            else: # 字母
                letterIndex.append(idx)
                L.append([i.lower(),i.upper()])
        if len(letterIndex)==0: # 没有字母
            return [S]
        else: # 有字母
            # 全排列等价于二进制数
            sortArray = []
            for i in range(2 ** len(letterIndex)):
                tmp = bin(i)[2:]
                while len(tmp) < len(letterIndex):
                    tmp = '0' + tmp
                sortArray.append(tmp)
            res = []
            for sort in sortArray:
                for ith in range(len(sort)):
                    str = list(str)
                    str[letterIndex[ith]] = L[letterIndex[ith]][int(sort[ith])]
                    str = ''.join(str)
                res.append(str)
            return res
    View Code

    (代码写的太不算法了,完全是拿数学和规律来解==,标准做法应该是构建一棵树,用递归来做)

    # 14 最长公共前缀:思路是先选取一个最短的字符串,然后与其他的进行比较,将模板字符串从长到短比较。

    def longestCommonPrefix(strs):
        minl=201
        mintemplate=''
        for i in strs: # 取最短的字符串作为模板来匹配其他的
            if len(i)<minl:
                minl=len(i)
                mintemplate=i
        for i in reversed(range(minl)):
            TrueFalseSet=set()
            for j in range(len(strs)):
                TrueFalseSet.add(mintemplate[:i+1]==strs[j][:i+1])
            if len(TrueFalseSet)==1 and list(TrueFalseSet)[0]==True:
                return mintemplate[:i+1]
            else:
                continue
        return ''
    View Code

    Follow this repo, update this blog continuously. 1.28 暂时停更,准备开始按类型刷。

  • 相关阅读:
    python+Appium自动化:记录遇到的坑
    python+Appium自动化:Appium元素检测
    python+Appium自动化:id元素定位
    python+Appium自动化:运行第一个appium脚本
    python+Appium自动化:Capability配置简介
    python+Appium自动化:Appium-desktop界面简介
    Appium简介以及环境安装
    monkeyrunner录制和回放功能
    monkeyrunner脚本录制和回放下载
    MonkeyRunner的简介与综合实践
  • 原文地址:https://www.cnblogs.com/pear-linzhu/p/14242346.html
Copyright © 2020-2023  润新知