跳转至

LeetCode

1. Two Sum

class Solution: # (1)
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]
  1. 🙋‍♂️ 2025/03/26
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            if target - num in hashtable:
                return [hashtable[target - num], i]
            hashtable[nums[i]] = i

2. Add Two Numbers

# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution: # (1)
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode(0)
        current = dummy
        carry = 0
        while l1 or l2 or carry:
            val1 = l1.val if l1 else 0
            val2 = l2.val if l2 else 0
            sum = val1 + val2 + carry
            carry = sum // 10
            current.next = ListNode(sum % 10)
            current = current.next
            l1 = l1.next if l1 else None
            l2 = l2.next if l2 else None
        return dummy.next
  1. 🙋‍♂️ 2025/03/27
# Remark: 思想一致
def create_linked_list(values): 
    dummy = ListNode()
    current = dummy
    for val in values:
        current.next = ListNode(val)
        current = current.next
    return dummy.next

l1 = create_linked_list([2, 4, 3])
l2 = create_linked_list([5, 6, 4])

while l1:
    print(l1.val) # 2\n 4\n 3
    l1 = l1.next
// typedef struct ListNode {
//     int val;
//     struct ListNode* next;
// } ListNode;
// 避免一直写struct, 直接用typedef

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* dummy = (ListNode*)malloc(sizeof(ListNode));
    dummy->next = NULL;
    ListNode* current = dummy;
    int carry = 0;
    while (l1 || l2 || carry) {
        int a = l1 ? l1->val : 0;
        int b = l2 ? l2->val : 0;
        int sum = a + b + carry;
        carry = sum / 10;
        current->next = (ListNode*)malloc(sizeof(ListNode));
        current->next->val = sum % 10;
        current->next->next = NULL;
        current = current->next;
        if (l1) l1 = l1->next;
        if (l2) l2 = l2->next;
    }
    ListNode* result = dummy->next;
    free(dummy); // 避免内存泄漏
    return result;
}
// Remark: 思想一致
ListNode* createNode(int val) {
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}

ListNode* createList(int* nums, int size) {
    ListNode* dummy = createNode(0);
    ListNode* current = dummy;
    for (int i = 0; i < size; i++) {
        current->next = createNode(nums[i]);
        current = current->next;
    }
    return dummy->next;
}

int main() {
    int nums[] = {2, 4, 3};
    int nums[] = {5, 6, 4};
    ListNode* l1 = createList(nums, 3);
    ListNode* l2 = createList(nums, 3);
    ListNode* result = addTwoNumbers(l1, l2);
    free(l1);
    free(l2);
    free(result);
    return 0;
}

3. Longest Substring Without Repeating Characters

class Solution: # (1) 运行提交笑嘻嘻,一看击败百分七🤡
    def lengthOfLongestSubstring(self, s: str) -> int:
        countset = []
        for num, i in enumerate(s):
            count = 1
            ls = [i]
            for j in range(num+1, len(s)):
                if s[j] not in ls:
                    ls.append(s[j])
                    count += 1
                else:
                    break
            countset.append(count)
        if countset == []:
            return 0
        else:
            return max(countset)
  1. 🙋‍♂️ 2025/03/27
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
            window_chars = set()
            n = len(s)
            left = 0
            max_len = 0
            for right in range(n):
                while s[right] in window_chars:
                    window_chars.remove(s[left])
                    left += 1
                window_chars.add(s[right])
                max_len = max(max_len, right - left + 1)
            return max_len

4. Median of Two Sorted Arrays

# 合并排序秒了,但合并时间复杂度为O(m+n), 排序采用Timsort算法,时间复杂度变为O((m+n)log(m+n))
class Solution:  # (1)
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        combine = sorted(nums1 + nums2)
        n = len(combine)
        if n % 2 == 0:
            output = (combine[int(n/2 - 1)] + combine[int(n/2)]) / 2
        else:
            output = combine[n//2]
        return output
  1. 🙋‍♂️ 2025/03/27
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        def getKthElement(k):
            """
            - 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
            - 这里的 "/" 表示整除
            - nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
            - nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
            - 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
            - 这样 pivot 本身最大也只能是第 k-1 小的元素
            - 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
            - 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
            - 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
            """

            index1, index2 = 0, 0
            while True:
                # 特殊情况
                if index1 == m:
                    return nums2[index2 + k - 1]
                if index2 == n:
                    return nums1[index1 + k - 1]
                if k == 1:
                    return min(nums1[index1], nums2[index2])

                # 正常情况
                newIndex1 = min(index1 + k // 2 - 1, m - 1)
                newIndex2 = min(index2 + k // 2 - 1, n - 1)
                pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]
                if pivot1 <= pivot2:
                    k -= newIndex1 - index1 + 1
                    index1 = newIndex1 + 1
                else:
                    k -= newIndex2 - index2 + 1
                    index2 = newIndex2 + 1

        m, n = len(nums1), len(nums2)
        totalLength = m + n
        if totalLength % 2 == 1:
            return getKthElement((totalLength + 1) // 2)
        else:
            return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2

5. Longest Palindromic Substring

class Solution: # (1)
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n == 0:
            return ""
        maxlen = 1
        maxstring = s[0]
        for i in range(n):
            # 奇数长度回文
            l, r = i, i
            while l >= 0 and r < n and s[l] == s[r]:
                if r - l + 1 > maxlen:
                    maxlen = r - l + 1
                    maxstring = s[l:r+1]
                l -= 1
                r += 1

            # 偶数长度回文
            l, r = i, i+1
            while l >= 0 and r < n and s[l] == s[r]:
                if r - l + 1 > maxlen:
                    maxlen = r - l + 1
                    maxstring = s[l:r+1]
                l -= 1
                r += 1

        return maxstring
  1. 🙋‍♂️ 2025/03/28

6. ZigZag Conversion

class Solution: # (1)
    def convert(self, s: str, numRows: int) -> str:
        if numRows == 1:
            return s
        output = []
        n = len(s)
        gap = numRows + (numRows - 2) # 完整“Z”字形的列间距

        for row in range(numRows):
            i = row
            while i < n:
                output.append(s[i])
                # 处理中间行(非首尾行)
                if row != 0 and row != numRows - 1:
                    j = i + gap - 2*row
                    if j < n:
                        output.append(s[j])
                i += gap 
        return "".join(output)
  1. 🙋‍♂️ 2025/03/28
class Solution: # 真是甜菜🤏
    def convert(self, s: str, numRows: int) -> str:
        if numRows < 2:
            return s
        res = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1:
                flag = -flag
            i += flag
        return "".join(res)

7. Reverse Integer

class Solution: # (1)
    def reverse(self, x: int) -> int:
        if x > 0:
            s = reversed(str(x))
            result = int("".join(s))
        elif x == 0:
            result = 0
        else:
            s = reversed(str(x)[1:])
            result = int("-" + "".join(s))

        if result < -2**31 or result > 2**31 - 1:
            return 0
        else:
            return result
  1. 🧀 2025/03/29
class Solution:
    def reverse(self, x: int) -> int:
        INT_MIN, INT_MAX = -2**31, 2**31 - 1
        sign = -1 if x < 0 else 1
        x_abs = abs(x)

        reversed_num = 0
        while x_abs != 0:
            digit = x_abs % 10
            x_abs = x_abs // 10

            # 检查反转后的数字是否可能溢出
            if sign == 1 and (reversed_num > (INT_MAX - digit) // 10):
                return 0
            if sign == -1 and (reversed_num > (abs(INT_MIN) - digit) // 10):
                return 0

            reversed_num = reversed_num * 10 + digit

        reversed_num *= sign
        return reversed_num

8. ASCII to Integer (atoi)

INT_MAX = 2**31 - 1
INT_MIN = -2**31

class Solution: # (1) 基本方法if else判断的shit mountain 就不写了,太烂了
    def myAtoi(self, s: str) -> int:
        automation = Automation()
        for c in s:
            automation.read(c)
        return automation.sign * automation.ans

class Automation:
    def __init__(self):
        self.state = "start"
        self.sign = 1
        self.ans = 0
        self.table = {
            "start" : ["start", "signed", "in_number", "end"],
            "signed" : ["end", "end", "in_number", "end"],
            "in_number" : ["end", "end", "in_number", "end"],
            "end" : ["end", "end", "end", "end"]
        }

    def get_col(self, c):
        if c.isspace():
            return 0
        if c == "+" or c == "-":
            return 1
        if c.isdigit():
            return 2
        return 3

    def read(self, c):
        self.state = self.table[self.state][self.get_col(c)]
        if self.state == "in_number":
            self.ans = self.ans * 10 + int(c)
            self.ans = min(self.ans, INT_MAX) if self.sign == 1 else min(self.ans, -INT_MIN)
        elif self.state == "signed":
            self.sign = 1 if c == "+" else -1
  1. ✅ 2025/03/31

class Solution:
def myAtoi(self, s: str) -> int:
    return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
^: start of string

[\+\-]: a single character of: +, -

?: zero or one

+: one or more

\d: Any digit

For more information: regex101

9. Palindrome Number

class Solution: # (1)
    def isPalindrome(self, x: int) -> bool:
        # 反转一半数字法
        # 特殊情况
        # 当x<0时,x不是回文数
        # 当数字的最后一位是0时,除非这个数字是0,否则都不满足回文性
        if x < 0 or (x % 10 == 0 and x != 0):
            return False

        revertednumber = 0
        while x > revertednumber:
            revertednumber = revertednumber * 10 + x % 10
            x = x // 10
        # 当数字长度为奇数时,我们可以通过revertednumber // 10去除处于中间位置的数字
        # 例如,当输入为12321时,在while循环的末尾我们可以得到 x = 12, revertednumber = 123
        # 因此我们可以将中位数字去除
        return x == revertednumber or x == revertednumber // 10
  1. ✅ 2025/04/01

10. Regular Expression Matching

class Solution: # (1) index非常绕,然后还有动态规划的思想,多琢磨吧
    def isMatch(self, s: str, p: str) -> bool:
        m, n = len(s) + 1, len(p) + 1
        dp = [[False] * n for _ in range(m)]
        dp[0][0] = True
        # 初始化首行
        for j in range(2, n, 2):
            dp[0][j] = dp[0][j - 2] and p[j - 1] == "*"
        # 状态转移
        for i in range(1, m):
            for j in range(1, n):

                if p[j - 1] == "*": # 当前字符为*时
                    if dp[i][j - 2]:
                        dp[i][j] = True
                    elif dp[i - 1][j] and s[i - 1] == p[j - 2]:
                        dp[i][j] = True
                    elif dp[i - 1][j] and p[j - 2] == ".":
                        dp[i][j] = True

                else: # 当前字符不为*时
                    if dp[i - 1][j - 1] and s[i - 1] == p[j - 1]:
                        dp[i][j] = True
                    elif dp[i - 1][j - 1] and p[j - 1] == ".":
                        dp[i][j] = True
        return dp[-1][-1]
  1. ✅ 2025/04/01

多看多想:k神图解

11. Container With Most Water

class Solution: # (1) 指针移动的基本原则是短板动。本题目为贪心算法的一种
    def maxArea(self, height: List[int]) -> int:
        left, right = 0, len(height) - 1
        res = 0
        while left < right:
            area = (right - left) * min(height[left], height[right])
            res = max(res, area)
            if height[left] < height[right]:
                left += 1
            else:
                right -= 1
        return res
  1. ✅ 2025/04/03

12. Integer to Roman

class Solution:
    VALUE_SIMPLES = [
        (1000, "M")
        (900, "CM"),
        (500, "D"),
        (400, "CD"),
        (100, "C"),
        (90, "XC"),
        (50, "L"),
        (40, "XL"),
        (10, "X"),
        (9, "IX"),
        (5, "V"),
        (4, "IV"),
        (1, "I"),
    ]

    def intToRoman(self, num: int) -> str:
        roman = list()
        for value, symbol in Solution.VALUE_SIMPLES:
            while num >= value:
                num -= value
                roman.append(symbol)
            if num == 0:
                break
        return "".join(roman)
class Solution:
    def intToRoman(self, num: int) -> str: # 1 <= num <= 3999
        REF = [
            ["I", "II", "III", "IV", "V", "VI", "VII","VIII", "IX"],
            ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
            ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
            ["M", "MM", "MMM"]
        ]
        digit = 0
        flag = 0
        s = ""
        for i in range(3, -1, -1):
            num = num - digit * flag
            flag = 10**i
            digit = num // flag
            if digit == 0:
                continue
            else:
                s = s + REF[i][digit - 1]
        return s