leetcode-python 第九周

LeetCode Online Judge
https://leetcode.com/

1. Four Sum [1192ms]

#方法1:先定两个,后面两个像2Sum一样用两个指针
class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        ans = []
        lth = len(nums)
        if lth < 4 :
            return ans

        nums.sort()
        for i in range(lth) :
            #跳过一个位重复
            if i > 0 and nums[i] == nums[i-1] :
                continue
            for j in range(i+1, lth) :
                #跳过第二位重复
                if j > i+1 and nums[j] == nums[j-1] :
                    continue
                low = j + 1
                high = lth - 1

                sum_ij = nums[i] + nums[j]

                while low < high :
                    if sum_ij + nums[low] + nums[high] < target :
                        low += 1
                    elif sum_ij + nums[low] + nums[high] > target :
                        high -= 1
                    else :
                        tmp = []
                        tmp.append(nums[i])
                        tmp.append(nums[j])
                        tmp.append(nums[low])
                        tmp.append(nums[high])
                        ans.append(tmp)
                        #这里如果不设置增加会死循环,但是又要避免重复
                        while low+1 < lth and nums[low] == nums[low+1] :
                            low += 1
                        low += 1
        return ans

2.First Missing Positive [64ms]

# 方法1:把元素放到合适的位置
#如果正数都超出数组范围,第一个就会搜索到1
class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(len(nums)) :
            while nums[i] != i + 1:
                # 如果超出数组大小,负数,或者重复
                if nums[i] >= len(nums) or nums[i] <= 0 or nums[i] == nums[nums[i]-1] :
                    break
                if i != nums[i] - 1 :
                    tmp = nums[i]
                    nums[i], nums[tmp-1] = nums[tmp-1], nums[i]

        for i in range(len(nums)) :
            if i != nums[i] - 1 :
                return i + 1

        return len(nums) + 1 

3.Insert Interval [552ms]

# 方法1:二分搜索到插入位置,然后向前检查,向后检查
# 方法2:参考discuss,运用栈
# Definition for an interval.
# class Interval(object):
#     def __init__(self, s=0, e=0):
#         self.start = s
#         self.end = e

class Solution(object):
    def insert(self, intervals, newInterval) :
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        insertIndex = self.binarySearch(intervals, newInterval)
        print('insertIndex', insertIndex)
        intervals.insert(insertIndex, newInterval)
        i = 0 if insertIndex == 0 else insertIndex - 1
        j = i + 1

        while j < len(intervals) :
            if intervals[i].end < intervals[j].start :
                break

            if intervals[j].end <= intervals[i].end :
                del intervals[j]
                j -= 1
            elif intervals[j].start <= intervals[i].end :
                intervals[i].end = intervals[j].end
                del intervals[j]
                j -= 1
            j += 1

        i = i + 1
        j = i + 1
        while j < len(intervals) :
            print('after', j)
            if intervals[i].end < intervals[j].start :
                break

            if intervals[j].end <= intervals[i].end :
                del intervals[j]
                j -= 1
            elif intervals[j].start <= intervals[i].end :
                intervals[i].end = intervals[j].end
                del intervals[j]
                j -= 1
            j += 1

        return intervals

    def binarySearch(self, intervals, newInterval):
        if len(intervals) == 0 :
            return 0

        low, high = 0, len(intervals)
        while low < high :
            mid = int((low + high) / 2)
            if intervals[mid].start == newInterval.start :
                return mid

            if intervals[mid].start < newInterval.start :
                low = mid + 1
            else :
                high = mid
        return low

class Solution(object):
    def insert(self, intervals, newInterval) :
        intervals.append(newInterval)
        intervals.sort(key=lambda intervals:intervals.start)
        if len(intervals) <= 1:
            return intervals
        ind = 1
        stack = []
        stack.append(intervals[0])
        while ind < len(intervals):
            I1 = stack[-1]
            I2 = intervals[ind]
            if I1.end >= I2.start:
                newI = Interval(min(I1.start, I2.start), max(I1.end, I2.end))
                stack.pop()
                stack.append(newI)
            else:
                stack.append(I2)
            ind += 1
        return stack

4. Jump Game II [76ms]

#方法1:别人的思路主要是考虑步数,而自己一直关注元素操作
#定义一个curRch表示前一步造成的搜索范围范围,maxRch表示这一步往后最远
#当遍历比curRch大,表明当前步数不能覆盖,i++
class Solution(object):
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        lth = len(nums)
        if lth < 2 :
            return 0

        curRch = 0
        maxRch = 0
        step = 0
        for i in range(lth) :
            if i > curRch :
                curRch = maxRch
                step += 1
            maxRch = max(maxRch, nums[i]+i)
        return step

5. Larget Rectangle in Histogram [120ms]

# 方法:http://www.cnblogs.com/felixfang/p/3676193.html
class Solution(object):
    def largestRectangleArea(self, heights):
        """
        :type heights: List[int]
        :rtype: int
        """
        stack = [] #记录下表的栈
        heights.append(0) #补上最后一个0
        lth = len(heights)
        i = 0
        ans = 0
        while i < lth :
            if len(stack) == 0 or heights[i] > heights[stack[-1]] : #当他是递增的,就堆栈
                stack.append(i)
            else :
                lowest = stack.pop() #以栈里的元素为最高,这样剩下栈顶的元素就是左边界,i为右边界
                # stack里面会一直留着一个最小的
                #向左算面积,stack=0是最后搜到0的情况
                ans = max(ans, heights[lowest] * (i if len(stack)==0 else i - stack[-1] - 1)) 
                i -= 1 #保持i在不是递增的突变位置
            i += 1
        return ans

6. Maximal Rectangle [148ms]

# 方法1:参照之前的最大矩型,每一行转化为高度。
# 参考discuss人家华丽的写法
class Solution(object):
    def maximalRectangle(self, matrix):
        """
        :type matrix: List[List[str]]
        :rtype: int
        """
        if not matrix or not matrix[0] :
            return 0

        ans = 0
        lth = len(matrix[0])
        height = [0] * (lth + 1)
        for row in matrix :
            for col in range(lth) :
                height[col] = height[col] + 1 if row[col] == "1" else 0
            # stack首先装入-1
            # 因为stack几乎永远转入一个最小数,而最小数恰好指向0
            # 防止stack为空时pop
            # 计算长度时 col-1-(-1)刚好等于col
            stack = [-1]
            for col in range(lth + 1) :
                while height[col] < height[stack[-1]] :
                    h = height[stack.pop()]
                    w = col - 1 - stack[-1]
                    ans = max(ans, w*h)
                stack.append(col)
        return ans

7. Word Search [1120ms]

# 方法1:dfs,先找到起点,在深度,用一个表记录是否被走过
class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        if len(board) == 0 or len(word) == 0 :
            return False

        m = len(board)
        n = len(board[0])
        starts = []
        visited = [[0 for i in range(n)] for j in range(m)]

        for i in range(m) :
            for j in range(n) :
                if board[i][j] == word[0] :
                    starts.append([i, j])
        for s in starts :
            flag = self.backtracking(board, s[0], s[1], word, 0, visited)
            if flag :
                return True
        return False

    def backtracking(self, board, i, j, word, k, visited) :
        dx = [0,0,1,-1]
        dy = [1,-1,0,0]

        if k == len(word)-1 and board[i][j] == word[k] and visited[i][j] == 0 :
            return True
        if board[i][j] != word[k] :
            return False
        for d in range(4) :
            if i+dx[d] >= 0 and i+dx[d] < len(board) and j+dy[d] >= 0 and j+dy[d] < len(board[0]) and visited[i][j] == 0 :
                visited[i][j] = 1
                flag = self.backtracking(board, i+dx[d], j+dy[d], word, k+1, visited)
                visited[i][j] = 0
                if flag :
                    return True
        return False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值