leetcode刷题日记-热题100(5)

337-打家劫舍3(python)
#完全背包0/1

class Solution:
    def rob(self,root):
    	def robinterger(root):
    		res=[0,0]
    		if not root:return res
    		left=robinterger(root.left)
    		right=robinterger(root.right)
    		res[0]+=max(left[0],left[1])+max(right[0],right[1])
    		res[1]+=root.val+left[0]+right[0]
    	robinterger(root)
    	return res

338-比特位计数(python)
#动态规划

class Solution:
    def countBits(self, num: int) -> List[int]:
        dp=[0]*(num+1)
        for i in range(1,num+1):
            if(i%2==1):
                dp[i]=dp[i-1]+1
            else:
                dp[i]=dp[i//2]
        return dp

347-前k个高频元素(python)
#dict

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        dict={}
        for num in nums:
            dict[num]=dict.get(num,0)+1
        dict=sorted(dict,key=dict.__getitem__,reverse=True)
        return dict[0:k]

581-最短无序连续子数组(python)
#找左右区间

class Solution:
    def findUnsortedArray(self,nums):
    	n=len(nums)
    	max_num=nums[0]
    	right=0
    	for i in range(n):
    		if nums[i]>=max_num:
    			max_num=nums[i]
    		else:
    			right=i
    	min_num=nums[n-1]
    	left=n-1
    	for j in range(n-1,-1,-1):
    		if nums[i]<=min_num:
    			min_num=nums[i]
    		else:
    			left=j
    	return right-left+1 if (right-left+1)>0 else 0

560-和为k的子数组(python)
#hash

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        hash={0:1}
        sum=0
        count=0
        for i in range(len(nums)):
            sum+=nums[i]
            if((sum-k) in hash):
                count+=hash[sum-k]
            if(sum in hash):
                hash[sum]+=1
            else:
                hash[sum]=1
        return count

543-二叉树的直径(python)

class Solution(object):
    def diameterOfBinaryTree(self, root):
        self.ans=1
        def depth(node):
            if not node: return 0
            L = depth(node.left)
            R = depth(node.right)
            self.ans = max(self.ans, L+R+1)
            return max(L, R) + 1

        depth(root)
        return self.ans - 1

337-打家劫舍3(python)
#深度优先 递归算法:先遍历右节点,再存储根节点,最后遍历左节点

class Solution:
    def convertBST(self, root: TreeNode) -> TreeNode:
         self.sum = 0
         def dfs(root):
             if not root: return root
             dfs(root.right)
             self.sum = self.sum + root.val
             root.val = self.sum
             dfs(root.left)
             return root
         return dfs(root)

647-回文子串(python)
#中心扩展法

class Solution(object):
    def countSubstrings(self, s):
        def get_Center(s,l,r):
            count = 0
            while l>=0 and r<len(s) and s[l]==s[r]:
                l-=1
                r+=1
                count+=1
            return count            
        n = len(s)
        sum1 = 0
        for i in range(len(s)):
            count_even = get_Center(s,i,i)
            count_odd = get_Center(s,i,i+1)
            sum1 = sum1+count_even+count_odd
        return sum1

416-分割和子集(python)-给一数组分为等值的两个子集
#动态规划

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        n=len(nums)
        target=sum(nums)
        if(target%2!=0):
            return False
        target//=2
        dp=[[False]*(target+1) for _ in range(n)]
        dp[0][0]=True
        for i in range(1,target+1):
            if(nums[0]==i):
                dp[0][i]=True
                break
        for i in range(1,n):
            for j in range(target+1):
                if(j>=nums[i]):
                    dp[i][j]=dp[i-1][j] or (dp[i-1][j-nums[i]])
                else:
                    dp[i][j]=dp[i-1][j]
        return dp[-1][-1]

406-根据身高重建队列(python)
#先按身高降序排列,然后按照k值插入排序

class Solution(object):
    def reconstructQueue(self, people):
        people.sort(key=lambda (h, k): (-h, k))
		res=[]
		for p in people:
			res.insert(p[1],p)
		return res

494-目标和(python)
#转换为求数组中子集满足正数V

class Solution:
    def findTargetSumWays(self, nums: List[int], S: int) -> int:
        if (sum(nums)+S)%2!=0 or sum(nums)<S:
            return 0
        V=(sum(nums)+S)//2
        dp=[0]*(V+1)
        dp[0]=1
        for num in nums:
            i=V
            while i>=num:
                dp[i]+=dp[i-num]
                i-=1
        return dp[-1]

448-找到数组中消失的数字(python)
#将不等于i+1的index值放在其正确位置上

class Solution:
    def findDisappearNumbers(self,num):
    	res=[]
    	for i in range(len(nums):
    		while nums[i]!=i+1 and nums[i]!=nums[nums[i]-1]:
    			nums[i],nums[nums[i]-1]=nums[nums[i]-1],nums[i]
    	for i in range(len(nums)):
    		if nums[i]!=i+1:
    			res.append(i+1)
    	return res

437-路径总和3(python)

class Solution(object):
    def pathSum(self, root, sum):
        if not root:
            return 0
        # target 所有路径所能构成的和列表
        def dfs(node, target):
            if not node:
                return 0
            # 左右的值默认为0
            l, r = 0, 0
            # 之前的和依次加上当前节点的值,再添加当前节点
            target = [node.val] + [_ + node.val for _ in target]
            # 递归
            l = dfs(node.left, target)
            r = dfs(node.right, target)
            # 计算当前的路径和等于给定数值的个数
            return target.count(sum) + l + r
        return dfs(root, [])

438-找到字符串中所有字母异味词(python)

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        res=[]
        window={}
        needs={}
        for c in p:needs[c]=needs.get(c,0)+1
        left=right=0
        while right<len(s):
            c=s[right]
            if c not in needs:
                window.clear()
                left=right=right+1
            else:
                window[c]=window.get(c,0)+1
                if right-left+1==len(p):
                    if window==needs:
                        res.append(left)
                    window[s[left]]-=1
                    left+=1
                right+=1
        return res

309-最佳股票买卖时机(python)
#动态规划

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices: return 0
        l = len(prices)
        dp = [[0, 0] for _ in range(l+1)]
        dp[0][1] = float('-inf')
        dp[1][1] = -prices[0]
        for i in range(2, l+1): # 因为下面有i-2所以从2开始, 自行去填0-1的base case
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i-1])
            dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i-1])
        return dp[-1][0]

312-戳气球(python)
#动态规划

class Solution:
    def maxCoins(self, nums: List[int]) -> int:
        nums = [1]+nums+[1]
        l = len(nums)
        # print(nums)
        dp = [[0]*l for _ in range(l)] # dp[i][j][i,j]之间的最大值, 注意这里不能选i或j去戳破, 否则子问题会有重叠
        for i in range(l-3, -1, -1): # 这点是从后往前! 要使小范围的[i,j]先被计算!!
            for j in range(i+2, l):
                for k in range(i+1, j):
                    dp[i][j] = max(dp[i][j], dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j])
        return dp[0][-1]

394-字符串解码(python)

class Solution:
    def decodeString(self, s: str) -> str:
        stack, res, multi = [], "", 0
        for c in s:
            if c == '[':
                stack.append([multi, res])
                res, multi = "", 0
            elif c == ']':
                cur_multi, last_res = stack.pop()
                res = last_res + cur_multi * res
            elif '0' <= c <= '9':
                multi = multi * 10 + int(c)            
            else:
                res += c
        return res

你可能感兴趣的:(leetcode刷题日记-热题100(5))