AHK Leetcode系列 21-30

写在最前

注:由于单版面容不下665道题,因此拆分,之后会单做一个目录。

**答案有误请私信告知,谢谢。

这是由Mono开展的第一个长期项目,会将Leetcode相关习题通过AHKv2实现,每道题会同步贴出相应Python代码。对一些Python程序员而言,可以通过比较,更快迁移到AHK这门语言上。

***引流:请喜欢Python的或是对于人工智能感兴趣的程序员关注我的另一个(大概)每周更新项目《Sinet库》,目前已经迁移了包括Numpy、Pandas和Sklearn在内的大量Python相关函数内容。

更新至第三十题 2022.07.10 Mono

第二十一题 合并两个有序链表

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
合并两个已排序的链表,并将其作为新列表返回。新列表应通过将前两个列表的节点拼接在一起来创建。
Python
# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = dummy = ListNode(-1)
        while l1 and l2:
            if l1.val < l2.val:
                head.next = l1
                l1 = l1.next
            else:
                head.next = l2
                l2 = l2.next
            head = head.next
        if l1:
            head.next = l1
        if l2:
            head.next = l2
        return dummy.next
AutoHotkey
; Definition for singly-linked list.
class ListNode
{
    __New(x)
    {
        this.val := x
        this.next := ""
    }
}

class Solution
{
    static mergeTwoLists(l1, l2)
    {
        head := dummy := ListNode(-1)
        while l1 and l2
        {
            if l1.val < l2.val
            {
                head.next := l1
                l1 := l1.next
            }
            else
            {
                head.next := l2
                l2 := l2.next
            }
            head := head.next
        }
        if l1
            head.next := l1
        if l2
            head.next := l2
        return dummy.next
    }
}
; Create List_Node
; a := ListNode(1)
; a_head := a
; arr := [2, 4]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; a.next := temp
    ; a := a.next
; }

; b := ListNode(1)
; b_head := b
; arr := [3, 4]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; b.next := temp
    ; b := b.next
; }

; Check Solution
; 这里提供了一种直观看链表的办法
; res := Solution.mergeTwoLists(a_head, b_head)
; res_text := ""
; while res
; {
    ; res_text .= res.val "->"
    ; res := res.next
; }
; msgBox SubStr(res_text, 1, strlen(res_text) - 2)

第二十二题 括号生成(含DFS算法)

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
给定n对括号,编写一个函数来生成格式良好的括号的所有组合。

For example, given n = 3, a solution set is:
[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]
Python
class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        def dfs(left, path, res, n):
            if len(path) == 2 * n:
                if left == 0:
                    res.append("".join(path))
                return
            
            if left < n:
                path.append("(")
                dfs(left + 1, path, res, n)
                path.pop()
            if left > 0:
                path.append(")")
                dfs(left - 1, path, res, n)
                path.pop()
            
        res = []
        dfs(0, [], res, n)
        return res
AutoHotkey
class Solution
{
    static generateParenthesis(n)
    {
        dfs(left, path, res, n)
        {
            if path.length == 2 * n
            {
                if left == 1
                {
                    tmp := ""
                    for i in path
                        tmp .= i
                    res.push(tmp)
                }
                return
            }
            
            if left <= n
            {
                path.push("(")
                dfs(left + 1, path, res, n)
                path.pop()
            }
            if left > 1
            {
                path.push(")")
                dfs(left - 1, path, res, n)
                path.pop()
            }
        }
        res := []
        dfs(1, [], res, n)
        return res
    }
}
; Check Solution
; 为了便于测试我引入比较简单的Print办法,Sinet库中有更强的Print
; print Solution.generateParenthesis(3)

Print(Text)
{
    msgBox ToString(Text)
}

ToString(Text)
{
    Print_Text := ""
    if Type(Text) == "Array"
    {
        Print_Text .= "["
        For i in Text
            Print_Text .= ToString(i) ","
        Print_Text := SubStr(Print_Text, 1, StrLen(Print_Text) - 1)
        Print_Text .= "]"
    }
    else
        Print_Text .= Text
    
    Return Print_Text
}

第二十三题 合并K个升序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
合并k个已排序的链表,并将其作为一个已排序的列表返回。分析并描述其复杂性。
Python
# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None
import heapq
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        heap = []
        p = dummy = ListNode(-1)
        for i in xrange(0, len(lists)):
            node = lists[i]
            if not node:
                continue
            heapq.heappush(heap, (node.val, node))
        
        while heap:
            value, node = heapq.heappop(heap)
            p.next = node
            p = p.next
            if node.next:
                node = node.next
                heapq.heappush(heap, (node.val, node))
        return dummy.next
AutoHotkey
; Definition for singly-linked list.
class ListNode
{
    __New(x)
    {
        this.val := x
        this.next := ""
    }
}

; ahk没有xrange函数,这里提供一个简单版本,在Sinet库中有更好的Range函数
xrange(length)
{
    arr := []
    loop length
        arr.push(A_Index-1)
    return arr
}

; ahk没有heapq模块,这里写一个简单的替代,Sinet库中暂时无相关内容
class heapq
{
    static _siftdown(heap, startpos, pos)
    {
        newitem := heap[pos]
        while pos > startpos
        {
            parentpos := ((pos - 2) >> 1) + 1
            parent := heap[parentpos]
            if this.cmp_lt(newitem, parent)
            {
                heap[pos] := parent
                pos := parentpos
                continue
            }
            break
        }
        heap[pos] := newitem
    }
    
    static _siftup(heap, pos)
    {
        endpos := heap.length + 1
        startpos := pos
        newitem := heap[pos]
        childpos := 2 * pos
        while childpos < endpos
        {
            rightpos := childpos + 1
            if rightpos < endpos and not this.cmp_lt(heap[childpos], heap[rightpos])
                childpos := rightpos
            heap[pos] := heap[childpos]
            pos := childpos
            childpos := 2 * pos
        }
        heap[pos] := newitem
        this._siftdown(heap, startpos, pos)
    }
    
    static cmp_lt(x, y)
    {
        return x[1] < y[1]
    }
    
    static heappop(heap)
    {
        lastelt := heap.pop()
        if heap.length
        {
            returnitem := heap[1]
            heap[1] := lastelt
            this._siftup(heap, 1)
        }
        else
            returnitem := lastelt
        return returnitem
    }
    
    static heappush(heap, arr)
    {
        heap.push(arr)
        this._siftdown(heap, 1, heap.length)
    }
}

class Solution
{
    static mergeKLists(lists)
    {
        heap := []
        p := dummy := ListNode(-1)
        for i in xrange(lists.length)
        {
            node := lists[i + 1]
            if not node
                continue
            heapq.heappush(heap, [node.val, node])
        }
        while heap.length
        {
            tmp := heapq.heappop(heap)
            value := tmp[1]
            node := tmp[2]
            p.next := node
            p := p.next
            if node.next
            {
                node := node.next
                heapq.heappush(heap, [node.val, node])
            }
        }
        return dummy.next
    }
}
; Create List_Node
; a := ListNode(1)
; a_head := a
; arr := [4, 5]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; a.next := temp
    ; a := a.next
; }
; b := ListNode(1)
; b_head := b
; arr := [3, 4]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; b.next := temp
    ; b := b.next
; }
; c := ListNode(2)
; c_head := c
; arr := [6]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; c.next := temp
    ; c := c.next
; }

; Check Solution
; 这里提供了一种直观看链表的办法
; res := Solution.mergeKLists([a_head, b_head, c_head])
; res_text := ""
; while res
; {
    ; res_text .= res.val "->"
    ; res := res.next
; }
; msgBox SubStr(res_text, 1, strlen(res_text) - 2)

第二十四题 两两交换链表中的节点

Given a linked list, swap every two adjacent nodes and return its head.
给定一个链表,每隔两个相邻节点交换一次,并返回其头部。
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
您的算法应该只使用常量空间。您不能修改列表中的值,只能更改节点本身。
Python
# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """

        def reverseList(head, k):
            pre = None
            cur = head
            while cur and k > 0:
                tmp = cur.next
                cur.next = pre
                pre = cur
                cur = tmp
                k -= 1
            head.next = cur
            print(cur.val)
            return cur, pre

        if not head or not head.next:
            return head
        ret = head.next
        p = head
        pre = None
        while p:
            next, newHead = reverseList(p, 2)
            if pre:
                pre.next = newHead
            pre = p
            p = next
        return ret
AutoHotkey
; Definition for singly-linked list.
class ListNode
{
    __New(x)
    {
        this.val := x
        this.next := ""
    }
}
; 没什么值得注释的,跟之前的链表没啥大的差别
class Solution
{
    static swapPairs(head)
    {
        ; 注意这里函数一定要加上static,否则会被反复定义导致结果出现问题
        static reverseList(head, k)
        {
            pre := ""
            cur := head
            while cur and k > 0
            {
                tmp := cur.next
                cur.next := pre
                pre := cur
                cur := tmp
                k -= 1
            }
            head.next := cur
            return [cur, pre]
        }
        
        if not head or not head.next
            return head
        ret := head.next
        p := head
        pre := ""
        while p
        {
            tmp := reverseList(p, 2)
            next := tmp[1]
            newHead := tmp[2]
            if pre
                pre.next := newHead
            pre := p
            p := next
        }
        return ret
    }
}
; Create List_Node
; a := ListNode(1)
; a_head := a
; arr := [2, 3, 4]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; a.next := temp
    ; a := a.next
; }

; Check Solution
; 这里提供了一种直观看链表的办法
; res := Solution.swapPairs(a_head)
; res_text := ""
; while res
; {
    ; res_text .= res.val "->"
    ; res := res.next
; }
; msgBox SubStr(res_text, 1, strlen(res_text) - 2)

第二十五题 k个一组翻转链表

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
给定一个链表,每次反转链表k的节点,并返回其修改后的列表。
k是一个正整数,小于或等于链表的长度。如果节点数不是k的倍数,那么最后被忽略的节点应该保持不变。
您不能更改节点中的值,只能更改节点本身。
只允许使用恒定内存。

For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Python
# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        def reverseList(head, k):
            pre = None
            cur = head
            while cur and k > 0:
                tmp = cur.next
                cur.next = pre
                pre = cur
                cur = tmp
                k -= 1
            head.next = cur
            return cur, pre
            
        length = 0
        p = head
        while p:
            length += 1
            p = p.next
        if length < k:
            return head
        step = length / k
        ret = None
        pre = None
        p = head
        while p and step:
            next, newHead = reverseList(p, k)
            if ret is None:
                ret = newHead
            if pre:
                pre.next = newHead
            pre = p
            p = next
            step -= 1
        return ret
            
AutoHotkey
; Definition for singly-linked list.
class ListNode
{
    __New(x)
    {
        this.val := x
        this.next := ""
    }
}

class Solution
{
    static reverseKGroup(head, k)
    {
        static reverseList(head, k)
        {
            pre := ""
            cur := head
            while cur and k > 0
            {
                tmp := cur.next
                cur.next := pre
                pre := cur
                cur := tmp
                k -= 1
            }
            head.next := cur
            return [cur, pre]
        }
        length := 0
        p := head
        while p
        {
            length += 1
            p := p.next
        }
        if length < k
            return head
        step := length / k
        ret := ""
        pre := ""
        p := head
        while p and step
        {
            tmp := reverseList(p, k)
            next := tmp[1]
            newHead := tmp[2]
            if !ret
                ret := newHead
            if pre
                pre.next := newHead
            pre := p
            p := next
            step -= 1
        }
        return ret
    }
}
; Create List_Node
; a := ListNode(1)
; a_head := a
; arr := [2, 3, 4, 5]
; Loop arr.length
; {
    ; temp := ListNode(arr[A_Index])
    ; a.next := temp
    ; a := a.next
; }

; Check Solution
; 这里提供了一种直观看链表的办法
; res := Solution.reverseKGroup(a_head, 3)
; res_text := ""
; while res
; {
    ; res_text .= res.val "->"
    ; res := res.next
; }
; msgBox SubStr(res_text, 1, strlen(res_text) - 2)

第二十六题 删除有序数组中的重复项

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
给定一个排序的数组,在适当的位置删除重复项,使每个元素只出现一次并返回新的长度。
不要为另一个数组分配额外的空间,您必须使用恒定内存就地执行此操作

For example,
Given input array nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
Python
class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) <= 1:
            return len(nums)
        slow = 0
        for i in xrange(1, len(nums)):
            if nums[i] != nums[slow]:
                slow += 1
                nums[slow] = nums[i]
        return slow + 1
AutoHotkey
; 之前提供了一个简单的xrange,这次用一个迭代器对象
; 优化执行代码,Sinet库中迭代方式已全面更换成这个
class xrange
{
    __New(length)
    {
        this.looptimes := length
    }
    
    __Enum(num)
    {
        index := this.looptimes
        return Fn
        
        Fn(&a)
        {
            a := this.looptimes - index
            return index-- > 0
        }
    }
}

class Solution
{
    static removeDuplicates(nums)
    {
        if nums.length <= 1
            return nums.length
        slow := 1
        for i in xrange(nums.length - 1)
            if nums[i + 1] != nums[slow]
            {
                slow += 1
                nums[slow] := nums[i + 1]
            }
        return slow + 1
    }
}
; Check Solution
; msgBox Solution.removeDuplicates([0, 1, 1, 2, 2, 2, 3, 4])

第二十七题 移除元素

Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
给定一个数组和一个值,删除该值的所有实例并返回新的长度。
不要为另一个数组分配额外的空间,您必须使用恒定内存就地执行此操作。
元素的顺序可以更改。你在新的长度之外留下什么无关紧要。

Example:
Given input array nums = [3,2,2,3], val = 3
Your function should return length = 2, with the first two elements of nums being 2.
Python
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        slow = -1
        for i in xrange(0, len(nums)):
            if nums[i] != val:
                slow += 1
                nums[slow] = nums[i]
        return slow + 1
AutoHotkey
; 之前提供了一个简单的xrange,这次用一个迭代器对象
; 优化执行代码,Sinet库中迭代方式已全面更换成这个
class xrange
{
    __New(length)
    {
        this.looptimes := length
    }
    
    __Enum(num)
    {
        index := this.looptimes
        return Fn
        
        Fn(&a)
        {
            a := this.looptimes - index
            return index-- > 0
        }
    }
}

class Solution
{
    static removeElement(nums, val)
    {
        slow := 0
        for i in xrange(nums.length)
            if nums[i + 1] != val
            {
                slow += 1
                nums[slow] := nums[i + 1]
            }
        return slow
    }
}
; Check Solution
; msgBox Solution.removeElement([1, 1, 2, 2, 3, 4, 2], 2)

第二十八题 查询指定子字符串

Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
执行strStr()。
返回目标在源字符串中第一次出现的索引,如果目标不是源字符串的一部分,则返回-1。
Python
class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        if len(haystack) == len(needle):
            if haystack == needle:
                return 0
            else:
                return -1
                
        for i in xrange(0, len(haystack)):
            k = i
            j = 0
            while j < len(needle) and k < len(haystack) and haystack[k] == needle[j]:
                j += 1
                k += 1
            if j == len(needle):
                return i
        return -1 if needle else 0
AutoHotkey
; 之前提供了一个简单的xrange,这次用一个迭代器对象
; 优化执行代码,Sinet库中迭代方式已全面更换成这个
class xrange
{
    __New(length)
    {
        this.looptimes := length
    }
    
    __Enum(num)
    {
        index := this.looptimes
        return Fn
        
        Fn(&a)
        {
            a := this.looptimes - index
            return index-- > 0
        }
    }
}
; 这道题我转化为ahk版本,等价于ahk的Instr函数
class Solution
{
    static strStr(haystack, needle)
    {
        if strlen(haystack) == strlen(needle)
        {
            if haystack == needle
                return 1
            else
                return -1
        }
        ; 由于要进行取值,因此转换为array类型
        haystack := StrSplit(haystack, "")
        needle := StrSplit(needle, "")
        for i in xrange(haystack.length)
        {
            k := i
            j := 0
            while j < needle.length and k < haystack.length and haystack[k + 1] == needle[j + 1]
            {
                j += 1
                k += 1
            }
            if j == needle.length
                return i + 1
        }
        return needle ? -1 : 1
    }
}
; Check Solution
; msgBox Solution.strStr("abcd", "bc")

第二十九题 两数相除

Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
不使用乘法、除法和mod运算符对两个整数进行除法。
如果溢出,则返回MAX_INT。
Python
class Solution(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        if divisor == 0:
            return 0x7fffffff
        sign = 1
        if dividend * divisor < 0:
            sign = -1
        ans = 0
        cnt = 1
        dividend = abs(dividend)
        divisor = abs(divisor)
        subsum = divisor
        while dividend >= divisor:
            while (subsum << 1) <= dividend:
                cnt <<= 1
                subsum <<= 1
            ans += cnt
            cnt = 1
            dividend -= subsum
            subsum = divisor
        return max(min(sign * ans, 0x7fffffff), -2147483648)
AutoHotkey
class Solution
{
   static divide(dividend, divisor)
   {
        if divisor == 0
            return 0x7fffffff
        sign := 1
        if dividend * divisor < 0
            sign := -1
        ans := 0
        cnt := 1
        dividend := abs(dividend)
        divisor := abs(divisor)
        subsum := divisor
        while dividend >= divisor
        {
            while (subsum << 1) <= dividend
            {
                cnt <<= 1
                subsum <<= 1
            }
            ans += cnt
            cnt := 1
            dividend -= subsum
            subsum := divisor
        }
        return max(min(sign * ans, 0x7fffffff), -2147483648)
    }
}
; Check Solution
; msgBox Solution.divide(5, -3)

第三十题 串联所有单词的子串

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
给你一个字符串s和一个单词列表,这些单词都是相同长度的。
在s中查找子串的所有起始索引,该子串是单词中每个单词准确连接一次,并且没有任何中间字符。

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).
Python
from collections import deque
class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if len(words) > len(s):
            return []
        d = {}
        t = {}
        ans = []
        deq = deque([])
        wl = len(words[0])
        fullscore = 0
        for word in words:
            d[word] = d.get(word, 0) + 1
            fullscore += 1
            
        for i in xrange(0, len(s)):
            head = start = i
            t.clear()
            score = 0
            
            while start + wl <= len(s) and s[start:start + wl] in d:
                cword = s[start:start + wl]
                t[cword] = t.get(cword, 0) + 1
                if t[cword] <= d[cword]:
                    score += 1
                else:
                    break
                start += wl

                
            if score == fullscore:
                ans.append(head)
        
        return ans
; 之前提供了一个简单的xrange,这次用一个迭代器对象
; 优化执行代码,Sinet库中迭代方式已全面更换成这个
class xrange
{
    __New(length)
    {
        this.looptimes := length
    }
    
    __Enum(num)
    {
        index := this.looptimes
        return Fn
        
        Fn(&a)
        {
            a := this.looptimes - index
            return index-- > 0
        }
    }
}
; 此题中deque库未用到,故删去
class Solution
{
    static findSubstring(s, words)
    {
        s := StrSplit(s, "")
        if words.length > s.length
            return []
        d := map()
        t := map()
        ans := []
        wl := strlen(words[1])
        fullscore := 0
        for word in words
        {
            d[word] := d.get(word, 0) + 1
            fullscore += 1
        }
            
        for i in xrange(s.length)
        {
            head := start := i
            t.clear()
            score := 0
            ; 这里之所以要用try是因为最后一次循环时会超索引
            ; 而python没问题是因为它的这段语句在while循环的判断语句中
            try
            {
                tmp := ""
                loop wl
                    tmp .= s[start + A_Index]
            }
            while start + wl <= s.length and inarr(tmp, d)
            {
                cword := tmp
                t[cword] := t.get(cword, 0) + 1
                if t[cword] <= d[cword]
                    score += 1
                else
                    break
                start += wl
                tmp := ""
                loop wl
                    tmp .= s[start + A_Index]
            }

                
            if score == fullscore
                ans.push(head)
        }
        
        return ans
    }
}
; Check Solution
; 为了便于测试我引入比较简单的Print办法,Sinet库中有更强的Print
print Solution.findSubstring("barfoothefoobarman", ["foo", "bar"])
Print(Text)
{
    msgBox ToString(Text)
}
ToString(Text)
{
    Print_Text := ""
    if Type(Text) == "Array"
    {
        Print_Text .= "["
        For i in Text
            Print_Text .= ToString(i) ","
        Print_Text := SubStr(Print_Text, 1, StrLen(Print_Text) - 1)
        Print_Text .= "]"
    }
    else
        Print_Text .= Text
    
    Return Print_Text
}
; 这里提供了一个简单的in关键字替换方案,Sinet库中的Sinet.In函数更强大
inarr(str, arr)
{
    flag := 0
    for i in arr
        if str == i
            flag := 1
    return flag
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他

上手AHK你所需要知道的事

2022-7-8 18:29:14

教程

AHK Leetcode系列 目录(AutoHotkey v2刷题挑战系列)

2022-7-10 13:09:44

2 条回复 A文章作者 M管理员
  1. AHK中文社区

    速度不错

  2. AHK中文社区
    1河许人给您打赏了¥5
个人中心
购物车
优惠劵
有新私信 私信列表
搜索