LeetCode 15 - 20 记录

15

https://leetcode.com/problems/3sum/

求所有满足三数之和为 0 的子数组。

这道题主要是利用双指针来做。

from typing import List
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        leng = len(nums)
        if (nums == None or leng < 3):
            return res
        nums.sort() # sort the nums list
        for i in range(leng):
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i - 1]: # remove the dumplicated
                continue
            # double pointers
            L = i + 1
            R = leng - 1
            while L < R:
                sum = nums[i] + nums[L] + nums[R]
                if sum == 0:
                    res.append([nums[i], nums[L], nums[R]])
                    while L < R and nums[L] == nums[L + 1]:
                        L = L + 1
                    while L < R and nums[R] == nums[R - 1]:
                        R = R - 1
                    L = L + 1
                    R = R - 1
                elif sum < 0:
                    L = L + 1
                else:
                    R = R - 1
        return res

if __name__ == '__main__':
    solu = Solution()
    input = [-1,0,1,2,-1,-4]
    output = solu.threeSum(input)
    print(output)

16

https://leetcode.com/problems/3sum-closest/

求三数之和最接近给定的 target 的情况。返回找到的三个数之和。

依然是双指针。

from typing import List
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        res = nums[0] + nums[1] + nums[2]
        for i in range(len(nums)):
            start = i + 1
            end = len(nums) - 1
            while start < end:
                sum = nums[i] + nums[start] + nums[end]
                if abs(target - sum) < abs(target - res):
                    res = sum
                if sum > target:
                    end = end - 1
                elif sum < target:
                    start = start + 1
                else:
                    return res
        return res
if __name__ == '__main__':
    solu = Solution()
    input = [-1,2,1,-4]
    target = 1
    output = solu.threeSumClosest(input, target)
    print(output)

17

from typing import List
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        res = []
        if len(digits) == 0 or digits == None:
            return  res
        mydict = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
        # print(len(digits))
        res = [[] for i in range(len(digits))]
        # print(res)
        res[0] = [s for s in mydict[digits[0]]]
        for i in range(1, len(digits)):
            for mystr in res[i - 1]:
                for s in mydict[digits[i]]:
                    res[i].append(mystr + s)
        return res[len(digits) - 1]

if __name__ == '__main__':
    solu = Solution()
    input = "23" 
    input = ""
    input = "2"
    output = solu.letterCombinations(input)
    print(output)

直观的想法是把这个电话号码的组合想象成一棵树,根节点是一个空字符串,然后根据输入的数字,一层一层地向下面生长。但是,这个和那种简单地暴力循环一样,是不容易实现的。注意到,这里的最终的结果字符串是有顺序的,所以,我们可以把上一次的结果暂存起来,然后把接下来一次的所有情况给遍历一下,生成新的一次的情况,直至最后得到想要的结果。上面的代码是把所有的中间结果都存储了起来。但是,实际上,我们只需要 size 为 2 的数组。因此,下面的代码进行了优化:

from typing import List
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        res = []
        if len(digits) == 0 or digits == None:
            return  res
        mydict = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
        # print(len(digits))
        res = [[] for i in range(len(digits))]
        # print(res)
        res[0] = [s for s in mydict[digits[0]]]
        for i in range(1, len(digits)):
            for mystr in res[i - 1]:
                for s in mydict[digits[i]]:
                    res[i].append(mystr + s)
        return res[len(digits) - 1]

if __name__ == '__main__':
    solu = Solution()
    input = "23" 
    input = ""
    input = "2"
    output = solu.letterCombinations(input)
    print(output)

18

from typing import List
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        res = set()
        nums.sort()
        # print(nums)
        for i in range(len(nums) - 3):
            num1 = nums[i]
            # print('num1:', num1)
            for j in range(i + 1, len(nums) - 2):
                num2 = nums[j]
                left = j + 1
                right = len(nums) - 1
                while left < right:
                    num3 = nums[left]
                    num4 = nums[right]
                    sum = num1 + num2 + num3 + num4
                    # print('sum:', sum)
                    if sum == target:
                        res.add((num1, num2, num3, num4))
                        left = left + 1
                    elif sum > target:
                        right = right - 1
                    else:
                        left = left + 1
        res = [list(each) for each in res]
        return res

if __name__ == '__main__':
    solu = Solution()
    input = [1, 0, -1, 0, -2, 2]
    input = [2, 2, 2, 2, 2]
    target = 0
    target = 8
    output = solu.fourSum(input, target)
    print(output)

一言以蔽之,双指针。

注意一点,最后要去重。所以我一开始使用了 set,最后再转化成 list。可是,这样似乎有效率问题,而且,本题应该有更好的方法。抽时间研究。

19

# use fast and slow pointer
# this method can't be forgot any more!!
from typing import Optional, List
# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        slow = head
        fast = head
        for i in range(n):
            fast = fast.next
        if fast == None:
            return slow.next
        while fast.next != None:
            slow = slow.next
            fast = fast.next
        slow.next = slow.next.next
        return head

def generate_linked_list(data:List):
    nodelist = []
    for d in data:
        nodelist.append(ListNode(d))
    for i in range(len(nodelist) - 1):
        nodelist[i].next = nodelist[i + 1]
    return nodelist[0]

def print_linked_list(head:ListNode):
    cursor = head
    print('Linked List: ', end='')
    while cursor != None:
        print(cursor.val, end=' ')
        cursor = cursor.next
    # print('head: ', head.val)
    print()

if __name__ == '__main__':
    headlist = [1, 2, 3, 4, 5]
    head = generate_linked_list(headlist)
    print('before removed:')
    print_linked_list(head)
    # print_linked_list(head)
    solu = Solution()
    n = 2
    res = solu.removeNthFromEnd(head, n)
    print('after removed:')
    print_linked_list(res)

经典快慢指针。

20

class Solution:
    def isValid(self, s: str) -> bool:
        strstack = []
        strstack.append(s[0])
        for ch in s[1:]:
            if len(strstack) == 0:
                strstack.append(ch)
                continue
            ch_lists = ['{', '[', '(']
            if strstack[-1] == '{':
                if ch == '}':
                    strstack.pop()
                    continue
                elif ch in ch_lists:
                    strstack.append(ch)
                    continue
                else:
                    return False
            if strstack[-1] == '[':
                if ch == ']':
                    strstack.pop()
                    continue
                elif ch in ch_lists:
                    strstack.append(ch)
                    continue
                else:
                    return False
            if strstack[-1] == '(':
                if ch == ')':
                    strstack.pop()
                    continue
                elif ch in ch_lists:
                    strstack.append(ch)
                    continue
                else:
                    return False
        return len(strstack) == 0

if __name__ == '__main__':
    solu = Solution()
    Input = "()"
    Input = "()[]{}"
    Input = "(]"
    Input = "([)]"
    # Input = "{[]}"
    # Input = "([])"
    Output = solu.isValid(Input)
    print(Output)

经典堆栈问题。


LeetCode 15 - 20 记录
http://fanyfull.github.io/2021/11/28/LeetCode-15-20-记录/
作者
Fany Full
发布于
2021年11月28日
许可协议