Leetcode题解 0022期

昨天竟然直接摸了……其实做了三道题,但是根本没有来得及放出来,但是最近事情确实越来越多了,周四和周五应该是一周最忙的两天,╮(╯▽╰)╭……不过应该总是因为没有克制住自己所以才会没有时间做事情吧……
我就算不做4道题,我也得至少做2~3道题,今天补上昨天落下的一期,共6道题。

0079题 单词搜索【Word Search】

题目:
给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.

题目相对严谨

经典题目无需注意太多

解题思路:
这题直接思路就应该是DFS,注意一下robust,然后和标记矩阵的设置即可,然后注意一下简单的优化,你搜索的是单词,所以当下这个格子应该对应你单词的第几位的那个,如果不是的话,就不搜索,post代码:

class Solution:
    def __init__(self):
        self.pos = list()
        self.n = self.m = 0
        self.flag = False
        self.l = 0
        self.target = ""
        self.direction = [[1,0],[-1,0],[0,1],[0,-1]]
    def search(self, board, x, y, s):
        if s == self.target: self.flag = True; return
        if len(s) >= self.l: return
        self.pos[x][y] = True
        for d in self.direction:
            if 0 <= x+d[0] <= self.n-1 and 0 <= y+d[1] <= self.m-1 and not self.pos[x+d[0]][y+d[1]] and board[x+d[0]][y+d[1]] == self.target[len(s)]:
                self.search(board, x+d[0], y+d[1], s+board[x+d[0]][y+d[1]])
                if self.flag: return
        self.pos[x][y] = False

    def exist(self, board, word):
        self.n = len(board)
        if self.n == 0: return False
        self.m = len(board[0])
        if self.m == 0: return False
        self.l = len(word)
        if self.l == 0 or self.l > self.n*self.m: return False
        self.target = word
        self.pos = [[False for col in range(self.m)] for row in range(self.n)]
        for i in range(self.n):
            for j in range(self.m):
                if board[i][j] == word[0]:
                    self.search(board,i,j,board[i][j])

        return self.flag

当然为了节省空间,也可以使用board循环使用的道理,这点不用多说,反正这道题应该没有办法在时间上面进行优化,只有搜索这一个途径。


0080题 删除排序数组中的重复项 II【Remove Duplicates from Sorted Array II】

题目:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例:

给定 nums = [1,1,1,2,2,3],
函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。
你不需要考虑数组中超出新长度后面的元素。

给定 nums = [0,0,1,1,1,1,2,3,3],
函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。
你不需要考虑数组中超出新长度后面的元素。

题目相对严谨

除Robust以外无需注意太多

解题思路:
这题是第26题的二代,26题的解法具体参见https://blog.csdn.net/bright_silmarillion/article/details/80628966

class Solution:
    def removeDuplicates(self, nums):
        l = len(nums)
        if l <= 2: return l
        idx = 2
        while idx < l:
            if nums[idx-2] == nums[idx]:
                nums.remove(nums[idx])
                l -= 1
            else:
                idx += 1

        return l

0081题 搜索旋转排序数组 II【Search in Rotated Sorted Array II】

题目:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。
进阶:

  • 这是 搜索旋转排序数组 的延伸题目,本题中的 nums 可能包含重复元素。
  • 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

示例:

输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true

输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false

题目相对严谨

除Robust外无需注意太多

解题思路:
这道题也是一道续集,第一代是第0033题,参见https://blog.csdn.net/bright_silmarillion/article/details/80632159
时间复杂度肯定有影响了,之前说搜索pivot的效率会从 O ( l o g n ) 退化到 O ( n ) ,这样就没有办法了,但是基本思路还是不变,仍然是必须找到pivot,然后二分。不过为什么不试试python的index功能呢?我们是高级语言来着(神气)


0082题 删除排序链表中的重复元素 II【Remove Duplicates from Sorted List II】

题目:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有重复出现的数字。

示例:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

输入: 1->1->1->2->3
输出: 2->3

题目相对严谨

指针链表题,一定要谨慎,一定要熟练!

解题思路:
这是下一道题的续集,其实本身就是训练一下如何删除node,或者换句话,如何链接两个node,这就相对而言非常简单了,上代码

class Solution:
    def deleteDuplicates(self, head):
        if head == None: return head
        p1 = head
        h = t = None
        while p1 != None:
            p2 = p1.next
            if p2 == None or p1.val != p2.val:
                if t == None:
                    h = t = p1
                else:
                    t.next = p1
                    t = t.next
                t.next = None
                p1 = p2
                continue

            while p2 != None and p1.val == p2.val: p2 = p2.next
            p1 = p2

        return h

0083题 删除排序链表中的重复元素【Remove Duplicates from Sorted List】

题目:
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例:

输入: 1->1->2
输出: 1->2

输入: 1->1->2->3->3
输出: 1->2->3

题目相对严谨

有上一道题的帮助,这题会相对简单一些

解题思路:
运用上一道题的代码,简单修改,直接出结果,这种东西都是一遍过的。

class Solution:
    def deleteDuplicates(self, head):
        if head == None: return head
        p1 = head
        h = t = None
        while p1 != None:
            p2 = p1.next
            if t == None:
                h = t = ListNode(p1.val)
            else:
                t.next = ListNode(p1.val)
                t = t.next
            while p2 != None and p2.val == p1.val: p2 = p2.next
            p1 = p2
        return h

0084题 柱状图中最大的矩形【Largest Rectangle in Histogram】

题目:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
这里写图片描述
这里写图片描述
示例:

输入: [2,1,5,6,2,3]
输出: 10

题目相对严谨

除Robust外无需注意太多

解题思路:
这道题第一反应和之前做过拿到接最大雨水的题目一样,分别是第0011题,0042题。
感觉仍然是用DP做会是最快的结果,放上代码:

class Solution:
    def largestRectangleArea(self, heights):
        n = len(heights)
        if n == 0: return 0
        left = [0]*n
        right = [0]*n

        left[0] = 0
        for i in range(1,n):
            left[i] = i
            j = i
            while left[j] - 1 >=0 and heights[left[j]-1] >= heights[i]:
                j = left[j] - 1
            left[i] = left[j]

        right[n-1] = n-1
        for i in range(n-2,-1,-1):
            right[i] = i
            j = i
            while right[j] + 1 <= n-1 and heights[right[j] + 1] >= heights[i]:
                j = right[j] + 1
            right[i] = right[j]

        res = -1
        for i in range(n):
            res = max(res, heights[i]*(right[i]-left[i]+1))

        return res

猜你喜欢

转载自blog.csdn.net/bright_silmarillion/article/details/80784022