LeetCode day day up

01两数之和

用哈希表(python字典)优化运行时间

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        n=len(nums)
        dic={}
        for i in range(n):
            res=target-nums[i]
            if dic.get(res)  is not None:
                return [dic[res],i]
            dic[nums[i]]=i
                   

02两数相加

基本链表操作

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        re=ListNode(0)#开头位置
        r=re# 操作指针
        carry=0
        while(l1 or l2):
            x=l1.val if l1 else 0
            y=l2.val if l2 else 0
            s=carry+x+y
            carry=s//10
            r.next=ListNode(s%10)
            r=r.next
            if(l1!=None): l1=l1.next
            if(l2!=None): l2=l2.next
        if carry>0:
            r.next=ListNode(1)
        
        return re.next
            
            
         

03无重复字符

滑动搜索窗口,加哈希表优化

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        n=len(s)
        ans=0
        dic={}
        i=0
        for j in range(n):
            if dic.get(s[j]) is not None:
                i=max(dic[s[j]]+1,i)# 如果需要将窗口起点移动
            ans=max(ans,j-i+1)# 评估窗口大小
            dic[s[j]]=j#更新字符记录
        
        return ans
            
        

04寻找两个有序数组的中位数

时间没要求的话直接进行归并排序,复杂度O(n)
时间复杂度要求高的话,需要进行二分查找,复杂度O(log n)

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        m=len(nums1)
        n=len(nums2)
        if m>n:
            nums1,nums2,m,n=nums2,nums1,n,m
        
        imin,imax,half_len=0,m,(m+n+1)//2
        
        while imin<=imax:
            i=(imin+imax)//2
            j=half_len-i
            if i<m and nums2[j-1]>nums1[i]:
                imin=i+1
            elif i>0 and nums1[i-1]>nums2[j]:
                imax=i-1
            else:
                if i==0: left=nums2[j-1]
                elif j==0: left=nums1[i-1]
                else: left = max(nums1[i-1],nums2[j-1])
                
                if (m+n)%2==1:
                    return left
                if i == m: right = nums2[j]
                elif j == n: right = nums1[i]
                else: right = min(nums1[i], nums2[j])
                
                return (left+right)/2.0       

05 最长回文子串
马拉车算法,复杂度O(n),先将将如ABAC字符串处理成~#A#B#A#C#的形式,最长子串的长度是回最长文半径减1,起始位置是中间位置减去半径再除以2,所以问题转化为找到中间位置和半径

class Solution:
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        ns="~#"
        for l in s:
            ns=ns+l+"#"
        maxl=-1
        p=[0]*len(ns)
        mx=0
        mid=0
        kid=0
        for i in range(1,len(ns)):
            if i <mx:
                p[i]=min(p[2*mid-i],mx-i)
            else:
                p[i]=1
        
            while i+p[i]<len(ns) and ns[i-p[i]]==ns[i+p[i]]:
                p[i]+=1
            
            if mx<i+p[i]:
                mid=i
                mx=i+p[i]
            
            if maxl<p[i]:
                maxl=p[i]
                kid=i
     
        sat=(kid-p[kid])//2
        slen=p[kid]-1
        
        return s[sat:sat+slen]

06 Z字形变换

找规律按行输出,周期2*numRows-2

class Solution:
    def convert(self, s: 'str', numRows: 'int') -> 'str':
        if numRows==1:
            return s
        
        l=len(s)
        cycl=2*numRows-2
        res=""
        for i in range(numRows):
            for j in range(0,l-i,cycl):
                res=res+s[j+i]
                if i>0 and i<numRows-1 and j+cycl-i<l:
                    res=res+s[j+cycl-i]
                
        return res          

07 整数反转

用字符串处理

class Solution:
    def reverse(self, x: 'int') -> 'int':
        str_x=str(x)
        flag=1
        if x<0:
            flag=-1
            str_x=str_x[1:]
            
        res=str_x[::-1]
        res=int(res)*flag
        if res>-2**31 and res<2**31-1:
            return res
        else:
            return 0

08 字符转整数

主要是考虑各种测试用例

class Solution:
    def myAtoi(self, str: 'str') -> 'int':
        set0={" ","-","+","1","2","3","4","5","6","7","8","9","0"}
        set1={"1","2","3","4","5","6","7","8","9","0"}
        if not str:
            return 0
       
        flag=1
        num=""
        index=0
        for i,s in enumerate(str):
            index=i
            if s not in set0:
                break
            if s=="-":
                flag=-1
                break
            if s=="+":
                break
            if s in set1:
                num=num+s
                break
        if str[index] not in set0:
            return 0
        
        if index+1<len(str):
            for s in str[index+1:]:
                if s in set1:
                    num=num+s
                else:
                    break
      
        if not num:
            return 0
        
        
        num=flag*int(num)
        if flag==-1:
            return max(-2**31,num)
        else:
            return min(2**31-1,num)
        

09 回文数

简单的字符串处理

class Solution:
    def isPalindrome(self, x: 'int') -> 'bool':
        if x<0:
            return False
        strx=str(x)
        rx=strx[::-1]
        rx=int(rx)
        return rx==x      

11 盛水最多的容器

class Solution:
    def maxArea(self, height: 'List[int]') -> 'int':
        i=0
        j=len(height)-1
        maxv=0
        
        while i!=j:
            maxv=max(min(height[i],height[j])*(j-i),maxv)
            if height[i]>height[j]:
                j=j-1
            else:
                i=i+1
        return maxv

13 罗马数字转数字

利用字典储存字符对应值,根据左边字符小于右边处理特殊情况

class Solution:
    def romanToInt(self, s: 'str') -> 'int':
        dic={"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
        res=0
        l=len(s)
        i=0
        while i<l:
            if i+1<l and 2*dic[s[i]]<dic[s[i+1]]:
                res=res+dic[s[i+1]]-dic[s[i]]
                i=i+2
            else:
                res=res+dic[s[i]]
                i=i+1      
        return res

15 三数之和

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res=[]
        if len(nums)<3:
            return  res
        maps={i:0 for i in nums}
        for i in nums:
            if i in maps:
                maps[i]+=1
        ls=list(maps.keys())
        ls.sort()
        
        for i in range(len(ls)-1):
            if ls[i]!=0 and maps[ls[i]]>=2 and maps.get(-2*ls[i]):
                res.append([ls[i],ls[i],-2*ls[i]])
            for j in range(i+1,len(ls)):
                t=-ls[i]-ls[j]
                if maps.get(t) and t<ls[j] and t>ls[i]:
                    res.append([ls[i],t,ls[j]])
        if ls[-1]!=0 and maps[ls[-1]]>=2 and maps.get(-2*ls[-1]):
            res.append([ls[-1],ls[-1],-2*ls[-1]])
        if maps.get(0) and maps[0]>=3:
            res.append([0,0,0])
        return res

最长公共前缀

主要是特殊情况处理

class Solution:
    def longestCommonPrefix(self, strs: 'List[str]') -> 'str':
        l=len(strs)
        if l==0:
            return ""
        maxl=len(strs[0])
        for i in range(l-1):
            k=0
            maxl=min(maxl,len(strs[i+1]))
            while k<maxl and strs[i][k]==strs[i+1][k]:
                k=k+1
            maxl=min(k,maxl)
            
            if maxl==0:
                return ""
        
        return strs[0][:maxl]
            
           

18 四数之和

和三数类似,注意去重

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums.sort()
        ll=len(nums)
        maps=set()
        res=[]
        if ll<4:
            return res
        for i in range(ll-3):
            for j in range(i+1,ll-2):
                l=j+1
                r=ll-1
                while l<r:
                    s=nums[i]+nums[j]+nums[l]+nums[r]
                    if s==target:
                        ans=str(nums[i])+str(nums[j])+str(nums[l])+str(nums[r])
                        if ans not in maps:
                            maps.add(ans)
                            res.append([nums[i],nums[j],nums[l],nums[r]])
                        l=l+1
                        r=r-1
                        
                    elif s<target:
                        l=l+1
                    else:
                        r=r-1
        
        return res
                        
                        
        

19 删除倒数第n个结点

注意处理删头的特殊情况

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        first=head
        second=head
        for i in range(n):
            second=second.next
        if second is None:
            return head.next
        while second.next:
            first=first.next
            second=second.next
        
        first.next=first.next.next
        
        return head
            

20 有效的括号

使用栈

class Solution:
    def isValid(self, s: 'str') -> 'bool':
        stack=[]
        set={")":"(","}":"{","]":"["}
        p=""
        for c in s:
            if c in set:
                tp=stack.pop() if stack else "#"
                if set[c]!=tp:
                    return False
            else:
                stack.append(c)
        
        return not stack

33 搜索旋转排序数组

二分一半有序一半无,或者先整理成有序(找旋转点)

class Solution:
    def bisearch(self,nums: List[int], target: int,l:int,r:int)->int:
        while l<=r:
            mid =(l+r)//2
            if nums[mid]==target:
                return mid
            if nums[mid]<target:
                l=mid+1
            if nums[mid]>target:
                r=mid-1
        return -1
    def ubisearch(self,nums: List[int], target: int,l:int,r:int)->int:
        if l>r:
            return -1
        mid=(l+r)//2
        # print(l,r,mid)
        if mid<0 or mid>=len(nums):
            return -1
        if nums[mid]==target: 
            return mid
        if nums[l]<=nums[mid]:
            if target>=nums[l] and target<=nums[mid]:
                r=mid-1
                return self.bisearch(nums,target,l,r)
            else:
                l=mid+1
                return self.ubisearch(nums,target,l,r)
        else:
            if target>=nums[mid] and target <=nums[r]:
                l=mid+1
                return self.bisearch(nums,target,l,r)
            else:
                r=mid-1
                return self.ubisearch(nums,target,l,r) 
        
    
    def search(self, nums: List[int], target: int) -> int:
        return self.ubisearch(nums,target,0,len(nums)-1) 

43 字符串相乘

完全模拟

class Solution:
    def add(self, num1: str, num2: str) -> str:
        if len(num1)<len(num2):
            num1,num2=num2,num1
        num1=num1[::-1]+"0"
        num2=num2[::-1]+"0"*(len(num1)-len(num2)+1)
        l=0
        carry=0
        res=""
        while l<len(num1):
            sums=int(num1[l])+int(num2[l])+carry
            res+=str(sums%10)
            carry=sums//10
            l=l+1
        
        if res[-1]=="0":
            res=res[:-1]
        return res[::-1]

    def singlemultiply(self, num1: str, num2: str) -> str:
        n2=int(num2)
        if n2==0:
            return "0"
        if n2==1:
            return num1
        num1=num1[::-1]+"0"
        res=""
        carry=0
        for n1 in num1:
            prod=int(n1)*n2+carry
            res+=str(prod%10)
            carry=prod//10
        if res[-1]=="0":
            res=res[:-1]
        return res[::-1]
        
        
    
            
    def multiply(self, num1: str, num2: str) -> str:
        if len(num1)<len(num2):
            num1,num2=num2,num1
        res=""
        for n2 in num2:
            res=self.add(res+"0",self.singlemultiply(num1,n2))
        return res
                    

50 快速幂

位运算版

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n<0:
            x=1/x
            n=-n
        ans=1
        while n!=0:
            if n&1 !=0:
                ans*=x
            x*=x
            n>>=1
            
        return ans
            
             

51 n 皇后

经典回溯法

class Solution(object):
    def check(self,s):
        if len(s)>len(set(s)):
            return False
        pl=[int(v)-i for i,v in enumerate(s)]
        pl2=[int(v)+i for i,v in enumerate(s)]
        if len(pl)>len(set(pl)) or len(pl2)>len(set(pl2)):
            return False
        return True
    def back(self,s,n,ans):
        if len(s)==n:
            ans.append(s)
        for i in range(n):
            if self.check(s+str(i)):
                self.back(s+str(i),n,ans)
    def printans(self,ans,n):
        anss=[]
        for a in ans:
            midans=[]
            for i in a:
                t=int(i)
                s="."*t+"Q"+"."*(n-1-t)
                midans.append(s)
            anss.append(midans)
        return anss
    def solveNQueens(self, n):
        """
        :type n: int
        :rtype: List[List[str]]
        """
        ans=[]
        self.back("",n,ans)
        print(self.printans(ans,n))    
        

52 n皇后2

只要求输出解法种数

class Solution(object):
    def totalNQueens(self, n):
        """
        :type n: int
        :rtype: int
        """
        def DFS(s,n,xy_diff,xy_sum):
            if len(s)==n:
                return 1
            ans=0
            for i in range(n):
                if (i not in s )and (len(s)-i) not in xy_diff and (i+len(s)) not in xy_sum:
                    ans+=DFS(s+[i],n,xy_diff+[len(s)-i],xy_sum+[i+len(s)])
            return ans
                        
        return(DFS([],n,[],[]))

88 合并有序数组(原地)

从后向前,处理特殊情况 m=0,n=0

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        
        if m==0 and n>0:
            for i in range(n):
                nums1[i]=nums2[i]
        if n==0:
            pass
        
        
        while m>0 and n>0:
            if nums2[n-1]>nums1[m-1]:
                nums1[m+n-1]=nums2[n-1]
                n-=1
            else:
                nums1[m+n-1]=nums1[m-1]
                m-=1
        if n>0:
            for i in range(n):
                nums1[i]=nums2[i] 

208 前缀树

用defaultdict字典实现

from collections import defaultdict
class TrieNode:
    def __init__(self):
        self.children = defaultdict(TrieNode)
        self.is_word = False
class Trie:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root=TrieNode()
        

    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        cur=self.root
        for w in word:
            cur=cur.children[w]
        cur.is_word=True
        

    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        cur=self.root
        for w in word:
            cur=cur.children.get(w)
            if cur is None:
                return False
        return cur.is_word
        

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        cur = self.root
        for w in prefix:
            cur = cur.children.get(w)
            if cur is None:
                return False
        return True


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

235 二叉搜索树的最近公共祖先

t 满足t.val>=p.val and t.val<=q.val,其中p.val<q.val

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        
        if p.val>q.val:
            p,q=q,p
        t=root
        
        while not (t.val>=p.val and t.val<=q.val):
            if t.val>q.val:
                t=t.left
            if t.val<p.val:
                t=t.right
        
        return t
        
        

294 二叉树序列化

先序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.
        
        :type root: TreeNode
        :rtype: str
        """
        s=""
        q=[root]
        while q:
            root=q.pop(0)
            if root:
                s+=str(root.val)
                q.append(root.left)
                q.append(root.right)
            else:
                s+="~"
            s+=","
        return s
                
        
        

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        ss=data.split(",")
        
        if ss[0]=="~":
            return None
        
        root=TreeNode(int(ss[0]))
        q=[root]
        i=1
        while q:
            c=q.pop(0)
    
            if ss[i]!="~": c.left=TreeNode(int(ss[i]))
            if ss[i+1]!="~": c.right=TreeNode(int(ss[i+1]))
            i=i+2
            if c.left: q.append(c.left)
            if c.right: q.append(c.right)
        
        return root
            
        
        

# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))

342 4的幂

4的幂可以表示0100 奇数位上为1,且只有一个1

class Solution:
    def isPowerOfFour(self, num: int) -> bool:
        if num<=0:
            return False
        else:
            return (num&(num-1))==0 and (num & 0x5555555555)!=0

326 3的幂

素数幂都同余,所以这道题等价于找最大的int型3的幂

class Solution(object):
    def isPowerOfThree(self, n):
        """
        :type n: int
        :rtype: bool
        """
        if n<=0:
            return False
        big3=3**19
        
        return big3%n==0

363 矩形区域不超过 K 的最大数值和

bisect排序插入

class Solution:
    def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
        M = len(matrix)
        N = len(matrix[0]) if M else 0
        
       
        ans = -10000086
        for x in range(N):
            sums = [0] * M
            for y in range(x, N):
                slist, num = [], 0
                for z in range(M):
                    sums[z] += matrix[z][y]
                    num += sums[z]
                    if num <= k:
                        ans = max(ans, num)
                    i = bisect.bisect_left(slist, num - k)
                    if i != len(slist):
                        ans = max(ans, num - slist[i])
                    bisect.insort(slist, num)
        return ans

1001 网格照明

类似于n皇后,但是要利用set和hashmap优化查询

from collections import defaultdict
class Solution:
    def gridIllumination(self, N, lamps, queries):
        r,c,dxy,sxy=defaultdict(int),defaultdict(int),defaultdict(int),defaultdict(int)
        ans=[]
        lamps_set=set(map(tuple,lamps))
        pxy=[(1,1),(1,0),(1,-1),(0,1),(0,-1),(-1,1),(-1,0),(-1,-1),(0,0)]
        for x,y in lamps_set:
            r[x]+=1
            c[y]+=1
            dxy[x-y]+=1
            sxy[x+y]+=1
        for x,y in queries:
            if r[x] or c[y] or dxy[x-y] or sxy[x+y]:
                ans.append(1)
                for dx,dy in pxy:
                    nx=dx+x
                    ny=dy+y
                    if (nx,ny) in lamps_set:
                        r[nx]-=1
                        c[ny]-=1
                        dxy[nx-ny]-=1
                        sxy[nx+ny]-=1
                        lamps_set.remove((nx,ny))
            else:
                ans.append(0)
            
        return ans


单调队列

# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, nums, size):
        # write code here
        ans=[]
        if len(nums)<1 or size>len(nums) or size<1:
            return ans
        if size==1 or len(nums)==1:
            return nums
        dds=[(nums[0],0)]
        ans=[nums[0]]
        i=1
        for i in range(1,len(nums)):
            if dds[0][1]<i-size+1:
                dds.pop(0)
#             print(nums[i],dds)
            v,t=dds[0]
            v2,t2=dds[-1]
            if nums[i]>=v:
                dds=[[nums[i],i]]
            elif nums[i]<v2:
                dds.append([nums[i],i])
            else:
                while dds[-1][0]<=nums[i]:
                    dds.pop()
                dds.append([nums[i],i])
                
            ans.append(dds[0][0])
        return ans[size-1:]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值