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

01-两数之和(python)
#比较/排序+指针

class Solution:
	def twosum(self,nums,target):
		for i in range(len(nums)):
			temp=nums[:i]
			if (target-nums[i]) in temp:
				j=temp.index(target-nums[i])
				break
		return [j,i]

03-无重复字符最长子串(python)
#滑动窗口

class Solution:
	def lengthOfLongestSubString(self,s):
		if not s:return 0
		lookup=set()
		max_len=0
		cur_len=0
		left=0
		for i in range(len(s)):
			cur_len+=1
			while s[i] in lookup:
				lookup.remove(s[left]
				cur_len+=1
			if cur_len>max_len:
				max_len=cur_len
			lookup.add(s[i])
		return max_len		

05-最长回文子串(python)
#动态规划-边界条件

class Solution:
	def longestPalindrome(self,s):
        size=len(s)
        if size<=1:
            return s
        longest_l=1
        res=s[0]
        dp=[[False for _ in range(size)] for _ in range(size)]
        for r in range(1,size):
            for l in range(r):
                if s[l] == s[r]:
                    if r - l < 3:
                        dp[l][r] = True
                    else:
                        dp[l][r] = dp[l + 1][r - 1]
                else:
                    dp[l][r] = False
                if dp[l][r]:
                    cur_len = r - l + 1
                    if cur_len > longest_l:
                        longest_l = cur_len
                        res = s[l:r + 1]
        return res

010-正则表达式匹配(python)

class Solution(object):
    def isMatch(self, s, p):
        if not p: return not s
        if not s and len(p) == 1: return False
        m, n = len(s) + 1, len(p) + 1
        dp = [[False for _ in range(n)] for _ in range(m)]
        # 初始状态
        dp[0][0] = True
        dp[0][1] = False
        for c in range(2, n):
            j = c - 1
            if p[j] == '*':
                dp[0][c] = dp[0][c - 2]        
        for r in range(1,m):
            i = r - 1
            for c in range(1, n):
                j = c - 1
                if s[i] == p[j] or p[j] == '.':
                    dp[r][c] = dp[r - 1][c - 1]
                elif p[j] == '*':       # ‘*’前面的字符匹配s[i] 或者为'.'
                    if p[j - 1] == s[i] or p[j - 1] == '.':
                        dp[r][c] = dp[r - 1][c] or dp[r][c - 2]
                    else:                       # ‘*’匹配了0次前面的字符
                        dp[r][c] = dp[r][c - 2] 
                else:
                    dp[r][c] = False
        return dp[m - 1][n - 1]

011-盛最多水的容器(python)
#双指针-移除短板

class Solution:
	def maxArea(self,height):
		i,j,res=0,len(height),0
		while i<j:
			if height[i]<height[j]:
				res=max(res,height[i]*(j-i))
				i+=1
			else:
				res=max(res,height[j]*(j-i))
				j-=1
		return res

015-三数之和(python)
#排序+双指针

class Solution:
    def threeSum(self, nums):
        nums.sort()
        res, k = [], 0
        for k in range(len(nums) - 2):
            if nums[k] > 0: 
                break # 1. because of j > i > k.
            if k > 0 and nums[k] == nums[k - 1]: 
                continue # 2. skip the same `nums[k]`.
            i, j = k + 1, len(nums) - 1
            while i < j: # 3. double pointer
                s = nums[k] + nums[i] + nums[j]
                if s < 0:
                    i += 1
                    while i < j and nums[i] == nums[i - 1]:
                         i += 1
                elif s > 0:
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]:
                         j -= 1
                else:
                    res.append([nums[k], nums[i], nums[j]])
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i - 1]: 
                        i += 1
                    while i < j and nums[j] == nums[j + 1]: 
                        j -= 1
        return res

017-电话号码的字母组合(python)
#回溯

class Solution:
    def letterCombinations(self, digits):
        phone = {'2': ['a', 'b', 'c'],
            '3': ['d', 'e', 'f'],
            '4': ['g', 'h', 'i'],
            '5': ['j', 'k', 'l'],
            '6': ['m', 'n', 'o'],
            '7': ['p', 'q', 'r', 's'],
            '8': ['t', 'u', 'v'],
            '9': ['w', 'x', 'y', 'z']}
        output=[]    
        def backtrack(combination, next_digits):
            if len(next_digits)==0:
                output.append(combination)
            else:
                for letter in phone[next_digits[0]]:
                    backtrack(combination+letter,next_digits[1:])
        if digits:
            backtrack('',digits)
        return output

019-删除链表倒数第n个节点(python)
#快慢指针、求链表需要先建空链表

class Solution:
    def removeNthFromEnd(self, head, n):
        if not head:return
        dummy=ListNode(0)
        dummy.next=head
        fast=dummy
        slow=dummy
        for i in range(n):
            fast=fast.next
        while fast and fast.next:
            fast=fast.next
            slow=slow.next
        slow.next=slow.next.next
        return dummy.next

020-有效的括号(python)

class Solution:
    def isValid(self, s):
        mapping={")":"(","]":"[","}":"{"}
        stack=[]
        for char in s:
            if char not in mapping:
                stack.append(char)
            else:#判断右括号
                top_element=stack.pop()
                if top_element!=mapping[char]:
                    return false
        return not stack

21-合并两个有序链表(python)

class Solution:
    def mergeTwoLists(self, l1, l2):
        prev=ListNode(0)
        prehead=prev
        while l1 and l2:
            if l1.val<=l2.val:
                prehead.next=l1
                l1=l1.next
            else:
                prehead.next=l2
                l2=l2.next
            prehead=prehead.next
        prehead.next=l1 if l1 is not None else l2
        return prev.next

22-括号生成(python)
#回溯

class Solution:
	def generateParenthesis(self,n):
		ans=[]
		def backtrack(S='',left=0,right=0):
			if len(s)==2*n:
				ans.append(S)
			if left<n:backtrack(S='(',left+1,right)
			if right<left:backtrack(S=')',left,right+1)
		backtrack()
		return ans

23-合并k个有序链表(python)
#分治,先合并2个

class Solution:
    def mergeKLists(self, lists):
		if not lists:return 
        n = len(lists)
        return self.merge(lists, 0, n-1)
    def merge(self,lists, left, right):
        if left == right:
            return lists[left]
        mid = (left + right) // 2
        l1 = self.merge(lists, left, mid)
        l2 = self.merge(lists, mid+1, right)
        return self.mergeTwoLists(l1, l2)
    def mergeTwoLists(self, l1, l2):
        prev=ListNode(0)
        prehead=prev
        while l1 and l2:
            if l1.val<=l2.val:
                prehead.next=l1
                l1=l1.next
            else:
                prehead.next=l2
                l2=l2.next
            prehead=prehead.next
        prehead.next=l1 if l1 is not None else l2
        return prev.next

31-下一个排列(python)
#倒序查找第一个减小的索引,排序后,与第一个较大的值做交换。

class Solution:
    def nextPermutation(self, nums) :
		for i in range(len(nums)-1, 0, -1):
            if nums[i] > nums[i-1]:
                res_nums = nums[i:]
                res_nums.sort()
                nums[i:] = res_nums
                for j in range(i, len(nums)):
                    if nums[j] > nums[i-1]:
                        nums[j], nums[i-1] = nums[i-1], nums[j]
                        return nums
        nums.sort()
        return nums

32-最长有效的括号(python)

class Solution:
	def longestValidParenthesis(self,s):
		maxnum=0
		stack=[-1]
		for i in range(len(s)):
			if s[i]=='(':stack.append(i)
			else:
				stack.pop()
				if not stack:stack.append(i)
				if stack:maxnum=max(maxnum,i-stack[-1])
		return maxnum

33-搜索旋转排序数组(python)
#找下降索引,二分查找

class Solution:
    def search(self, nums, target):
        def find_rotate_index(left, right):
            if nums[left] < nums[right]:
                return 0            
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] > nums[pivot + 1]:
                    return pivot + 1
                else:
                    if nums[pivot] < nums[left]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
        def search(left, right):
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] == target:
                    return pivot
                else:
                    if target < nums[pivot]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
            return -1
        n = len(nums)        
        if n == 0:
            return -1
        if n == 1:
            return 0 if nums[0] == target else -1         
        rotate_index = find_rotate_index(0, n - 1)        
        if nums[rotate_index] == target:
            return rotate_index
        if rotate_index == 0:
            return search(0, n - 1)
        if target < nums[0]:
            return search(rotate_index, n - 1)
        else:
            return search(0, rotate_index)

34-在排序数组中查找元素的第一个和最后一个位置(python)
#二分查找(有重复值)

class Solution(object):
    def searchRange(self, nums, target):
        length = len(nums)
        if length == 0:
            return [-1,-1]
        left,right = 0,length-1
        while left <= right:
            mid = (left+right) // 2
            if nums[mid] == target:
                right = left = mid
                while left-1 >= 0 and nums[left-1] == target:
                    left -= 1
                while right+1 <= length-1 and nums[right+1] == target:
                    right += 1
                return [left,right]
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return [-1,-1] 

39-组合总数(python)
#深度优先

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        size=len(candidates)
        if size==0:
            return []
        candidates.sort()
        path=[]
        res=[]
        self.dfs(candidates,0,size,path,res,target)
        return res
    def dfs(self,candidates,start,size,path,res,target):
        if target==0:
            res.append(path[:])
            return
        for index in range(start,size):
            ram=target-candidates[index]
            if ram<0:
                break
            path.append(candidates[index])
            self.dfs(candidates,index,size,path,res,ram)
            path.pop()

042-接雨水(python)
#双指针法

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        if not height:return 0
        n=len(height)
        ans=0
        left,right=0,n-1
        max_left,max_right=height[0],height[n-1]
        while left<right:
            max_left=max(max_left,height[left])
            max_right=max(max_right,height[right])
            if max_left<max_right:
                ans+=max_left-height[left]
                left+=1
            else:
                ans+=max_right-height[right]
                right-=1
        return ans

46-全排列(python)
#递归+交换

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def backtrack(first=0):
            if first==n:
                output.append(nums[:])
            for i in range(first,n):
                nums[first],nums[i]=nums[i],nums[first]
                backtrack(first+1)
                nums[first],nums[i]=nums[i],nums[first]
        output=[]
        n=len(nums)
        backtrack()
        return output

48-旋转图像(python)

class Solution:
	def rotate(self,matrix):
		n=len(matrix)
		for i in range(n):
			for j in range(i,n):
				matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j]
		for i in range(n):
			matrix[i].reverse()
		return matrix

128-最长连续序列(python)

class Solution:
	def longestConsecutive(self,nums):
		if not nums:return 0
		nums.sort()
		longest_streak=1
		current_streak=1
		for i in range(1,len(nums)):
			if nums[i]!=nums[i-1]:
				if nums[i]==nums[i-1]+1:
					current_streak+=1
				else:
					longest_streak=max(longest_streak,current_streak)
					current_streak=1
		return max(longest_streak,current_streak)

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