leetcode 21-30 总结

61 篇文章 0 订阅
54 篇文章 0 订阅

21. Merge Two Sorted Lists

方法:linked list

Merge two sorted linked lists and return it as a new sorted list. The new list should be made by splicing together the nodes of the first two lists.

Example 1:

img

Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]

Example 2:

Input: l1 = [], l2 = []
Output: []

Example 3:

Input: l1 = [], l2 = [0]
Output: [0]

Constraints:

  • The number of nodes in both lists is in the range [0, 50].
  • -100 <= Node.val <= 100
  • Both l1 and l2 are sorted in non-decreasing order.
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        temp = ListNode(1) # a temp pointer to store start position
        l3 = temp # a pointer to store each elemnet
        while l1 and l2: # if both have element. store the sorted value 
            if l1.val < l2.val:
                l3.next = l1 # store the element pointedd by l1
                l1 = l1.next # shift l1
            else:
                l3.next = l2 # # store the element pointedd by l2
                l2 = l2.next # shift l2
            l3 = l3.next # shift l3
        l3.next = l1 or l2 # stored the rest element
        return temp.next

在这里插入图片描述

  • step 1:

    • initialize, l1 = NodeList(1), l1.next = NodeList(2), l1.next.next = NodeList(4)
    • l2= NodeList(1), l2.next = NodeList(3), l2.next.next = NodeList(4)
    • l3 = temp = ListNode(1), can be any value
      在这里插入图片描述
  • step 2:

    • l2.val <= l1.val
    • l3.next = l2
    • l2 = l2.next
    • l3 = l3.next
  • other steps: the same as before
    JS:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    let temp = new ListNode();
    let l3 = temp;
    while (l1 && l2) {
        if (l1.val < l2.val) {
            l3.next = l1;
            l1 = l1.next;
        } else {
            l3.next = l2;
            l2 = l2.next;
        }
        l3 = l3.next;
    }
    l3.next = l1 || l2;
    return temp.next;
};

22. Generate Parentheses

方法: stack

1 遇到括号,按照栈来处理,因为括号的匹配一定是成对的,只有栈才可以得到有效括号,如果需要列举,就用到dfs收索。本题dfs就是二叉树的递归调用,并满足有效括号的输出。
函数在内存中是按照栈的形式存储,如果 n = 1,实际函数的执行如下:

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        stack = []
        res = []
        def backTrack(openN, closedN): # openN, closedN = 0, 0
            if openN == closedN == n: # n = 1
                res.append(''.join(stack))
            if openN < n: # openN = 0, n = 1
                stack.append('(') # stack = ['(']
                    # backTrack(openN+1, closedN): # # openN, closedN = 1, 0
                    if openN == closedN == n: # openN, closedN = 1, 0, n = 1, not execute
                        res.append(''.join(stack))
                    if openN < n: # openN = 1, n = 1, not execute
                        stack.append('(')
                        backTrack(openN+1, closedN)
                        stack.pop()
                    if closedN < openN: # closeN = 0, n = 1, execute
                        stack.append(')') # stack = ['(', ')']
                        # backTrack(openN, closedN+1)
                        if openN == closedN == n: # openN == closedN = 1, n = 1
                            res.append(''.join(stack)) # res = ['()']
                        if openN < n: # openN = 1, n = 1 not execute
                            stack.append('(')
                            backTrack(openN+1, closedN)
                            stack.pop()
                        if closedN < openN: # closedN = 1, openN = 1, not execute
                            stack.append(')')
                            backTrack(openN, closedN+1)
                            stack.pop()
                        stack.pop() # stack =  ['('], execute
                stack.pop() # stack =  [],  execute
            if closedN < openN: # closedN = 1, openN = 1, not execute
                stack.append(')')
                backTrack(openN, closedN+1)
                stack.pop()
        backTrack(0, 0) # above
        return res # res = ['()']

这样相当于至上而下执行代码。执行完之后栈空,继续在寻找下一个。当全部不满足是推出。
实际代码如下:

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        stack = []
        res = []
        def backTrack(openN, closedN):
            if openN == closedN == n:
                res.append(''.join(stack))
            if openN < n:
                stack.append('(')
                backTrack(openN + 1, closedN)
                stack.pop()
            if closedN < openN:
                stack.append(')')
                backTrack(openN, closedN + 1)
                stack.pop()
        backTrack(0, 0)
        return res

1 if openN < n: 表示入栈的顺序
2 if closedN < openN:得到有效的括号。
3 stack.pop():最后的栈空
4 if openN == closedN == n: 输出每一个结果。

23. Merge k Sorted Lists

方法:优先队列

这里需要注意heapq的引入,因为leetcode版本默认import, 但是在其他的IDE上需要:import heapq
heapq是对的意思, 最常用的是最为优先队列,是目前最好的方法。
可以大大降低时间。
如果无法本地运行,需要 import heapq 防止ide没有import。

method: pq

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        # pq
        pq = []
        q = dummy = ListNode(0)
        for item in lists:
            p = item
            while p:
                heapq.heappush(pq, p.val) # keep min heap
                p = p.next
        while pq:
            val = heapq.heappop(pq) # min number
            q.next = ListNode(val)
            q = q.next
        return dummy.next            

24. Swap Nodes in Pairs

method: linked list

这种题很难,只能多做练习,指针的操作需要满足成对的置换,然后移动

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        prev = dummy = ListNode(0)
        dummy.next = head
        curr = prev.next
        while curr and curr.next:
            next = curr.next
            curr.next = next.next
            next.next = prev.next
            prev.next = next
            prev = prev.next.next
            curr = curr.next
            if curr == None: # edge cases, if there is one or two nodes
                next = None
            else:
                next = curr.next
        return dummy.next

25. Reverse Nodes in k-Group

方法同24题,当24理解了,可以做25,首先需要求出长度, 然后按照24的原理,成对,改为k 组。方法完全一样。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        prev = dummy = ListNode(0)
        curr = head
        dummy.next = head
        length = 0
        while head:
            length += 1
            head = head.next
        for i in range(length // k):
            for j in range(k - 1):
                next = curr.next
                curr.next = next.next
                next.next = prev.next
                prev.next = next
            prev = curr
            curr = prev.next
        return dummy.next

26. Remove Duplicates from Sorted Array

method: 一次遍历,一个指针指向空位填充
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        index = 1
        for i in range(1, len(nums)):
            if nums[i-1] != nums[i]:
                nums[index] = nums[i]
                index += 1
        return index

27. Remove Element

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        i = len(nums) - 1
        while i >= 0:
            if nums[i] == val:
                nums.remove(nums[i])
            i -= 1   
        return len(nums)

28. Implement strStr()

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if needle == '':
            return 0
        if needle in haystack:
            return haystack.index(needle)
        else:
            return -1
            
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        n, h = len(needle), len(haystack)
        i, j, nxt = 1, 0, [-1]+[0]*n
        while i < n:                                # calculate next array
            if j == -1 or needle[i] == needle[j]:   
                i += 1
                j += 1
                nxt[i] = j
            else:
                j = nxt[j]
        i = j = 0
        while i < h and j < n:
            if j == -1 or haystack[i] == needle[j]:
                i += 1
                j += 1
            else:
                j = nxt[j]
        return i-j if j == n else -1

29. Divide Two Integers

底层的除法按照位移运算可以加快速度,然后相减

if not dividend:
            return 0
        sign = 1 if (dividend > 0 and divisor < 0) or (dividend < 0 and divisor > 0) else 0
        dividend = abs(dividend)
        divisor = abs(divisor)
        res = 0
        while dividend >= divisor:
            k = 0
            while dividend >= divisor << (k + 1):
                k += 1
            dividend -= (divisor << k)
            res += (1 << k)
        MAX_INT =  (1 << 31) - 1
        return -res if sign else min(res,MAX_INT)

30. Substring with Concatenation of All Words

方法:sliding window

1 i, j 为window大小, i为输出下标。
2 Counter统计每个单词出现个数, m_length代表单词长度,n_word代表单词数量,也是跳出循环的条件。
3 内循环如果是单词数量超过规定数量,可以提前退出。时间复杂度O(n^2), 因为是两层循环。但能够解决如此复杂的问题。

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        ans = []
        n_words, m_length = len(words), len(words[0])
        words = collections.Counter(words)
        
        for i in range(len(s) - n_words *m_length+1): # no need to iterate all
            tmp = collections.Counter()
            cnt = 0
            for j in range(i,i+n_words *m_length, m_length): # at most n*m characters in the sliding window 
                w = s[j:j+m_length]
                if w in words:
                    tmp[w]+=1
                    cnt+=1
                    if tmp[w]>words[w]: # ditch current sliding window
                        break
                    if cnt==n_words:
                        ans.append(i)
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值