update project structure

This commit is contained in:
2024-06-20 06:29:07 +08:00
parent 17b4ef8970
commit fdaa94a0fa
49 changed files with 35 additions and 4 deletions

48
leetcode_py/1.py Normal file
View File

@@ -0,0 +1,48 @@
# Give a list and a number.
# Return a list of indices of two numbers
class Solution:
def twoSum(self, nums: list[int], target: int) -> list[int]:
"""
answer = []
for i in range(len(nums)):
another = target - nums[i]
# both number in the list
if another in nums:
if nums[i] == another:
temp_list = nums.copy()
temp_list.pop(i)
if another in temp_list:
answer.append(i)
answer.append(temp_list.index(another) + 1)
return answer
if another not in temp_list:
continue
answer.append(i)
answer.append(nums.index(another))
return answer
return answer
"""
num_map = {}
for i, num in enumerate(nums):
complement = target - num
# reduce compare times
if complement in num_map:
return [num_map[complement], i]
num_map[num] = i
return []
test = [3, 2, 4]
TARGET_NUMBER = 6
a = Solution().twoSum(test, TARGET_NUMBER)
print(a)
test2 = [i for i in range(1, 10001)]
TARGET_NUMBER = 19999
print(test2[9998], test2[9999])
print(Solution().twoSum(test2, TARGET_NUMBER))

31
leetcode_py/100.py Normal file
View File

@@ -0,0 +1,31 @@
from typing import Optional
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None or q is None:
if p is None and q is None:
return True
return False
if p.val != q.val:
return False
if p.left and q.left:
if not self.isSameTree(p.left, q.left):
return False
elif p.left or q.left:
return False
if p.right and q.right:
if not self.isSameTree(p.right, q.right):
return False
elif p.right or q.right:
return False
return True

36
leetcode_py/101.py Normal file
View File

@@ -0,0 +1,36 @@
from typing import Optional
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if root is None:
return True
return self.isMirrorTree(root.left, root.right)
def isMirrorTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None or q is None:
if p is None and q is None:
return True
return False
if p.val != q.val:
return False
if p.left and q.right:
if not self.isMirrorTree(p.left, q.right):
return False
elif p.left or q.right:
return False
if p.right and q.left:
if not self.isMirrorTree(p.right, q.left):
return False
elif p.right or q.left:
return False
return True

18
leetcode_py/13.py Normal file
View File

@@ -0,0 +1,18 @@
# translate roman number strings to int
class Solution:
def romanToInt(self, s: str) -> int:
roman_map = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
num = 0
prev_value = 0
for char in reversed(s):
value = roman_map[char]
if value < prev_value:
num -= value
else:
num += value
prev_value = value
return num

19
leetcode_py/14.py Normal file
View File

@@ -0,0 +1,19 @@
# find the longest common prefix
# 1 <= strs.length <= 200
# 0 <=strs[i].length <= 200
# only lowercase
class Solution:
def longestCommonPrefix(self, strs: list[str]) -> str:
return_string = ""
i = 0
while i < len(strs[0]):
try:
for string in strs:
if string[i] != strs[0][i]:
return return_string
return_string += strs[0][i]
i += 1
except:
return return_string
return return_string

43
leetcode_py/1608.py Normal file
View File

@@ -0,0 +1,43 @@
from typing import List
class Solution:
def bin_specialArray(self, nums: List[int]) -> int:
nums.sort()
left, right = 0, len(nums)
while left <= right:
mid = (left + right) // 2
count = sum(1 for num in nums if num >= mid)
if count == mid:
return mid
elif count < mid:
right = mid - 1
else:
left = mid + 1
return -1
def specialArray(self, nums: List[int]) -> int:
"""
Determines if there is a special number x in the list such that there are exactly x elements
in the list that are greater than or equal to x.
Args:
nums (List[int]): The list of non-negative integers.
Returns:
int: The special number x, or -1 if no such number exists.
"""
nums.sort()
n = len(nums)
for x in range(1, n + 1):
# Count how many numbers are greater than or equal to x
count = sum(1 for num in nums if num >= x)
if count == x:
return x
return -1

16
leetcode_py/169.py Normal file
View File

@@ -0,0 +1,16 @@
# Majority Elements
# the majority elements will appears more than half times
# Use Boyer-Moore Voting Alogrithm
class Solution:
def majorityElements(self, nums: list[int]) -> int:
count = 0
candidate = None
for num in nums:
if count == 0:
candidate = num
count += 1 if num == candidate else -1
return candidate

49
leetcode_py/20.py Normal file
View File

@@ -0,0 +1,49 @@
# give a string s containing just '(', ')' and else
# determine if the input is valid
class Solution:
def isValid(self, s: str) -> bool:
"""
# too slow
symbol_dict = {"(": ")", "{": "}", "[": "]"}
stack = []
for i in s:
try:
stack_top = stack.pop()
except IndexError:
stack.append(i)
continue
try:
if symbol_dict[stack_top] == i:
continue
stack.append(stack_top)
except KeyError:
return False
stack.append(i)
if stack:
return False
return True
"""
# Optimized solution
bracket_map = {")": "(", "}": "{", "]": "["}
stack = []
for char in s:
if char in bracket_map:
top_element = stack.pop() if stack else "#"
if bracket_map[char] != top_element:
return False
else:
stack.append(char)
return not stack

26
leetcode_py/202.py Normal file
View File

@@ -0,0 +1,26 @@
# Happy Number
# Repeat the process until the number equal to 1, these are happy
# OR LOOP ENDLESS in a cycle, these are not happy
class Solution:
def isHappy(self, n: int, status=None) -> bool:
if status is None:
status = []
str_n = str(n)
total = 0
for number in str_n:
total += int(number) ** 2
if total == 1:
return True
if str(total) in status:
return False
status.append(str(total))
return self.isHappy(total, status)
if __name__ == "__main__":
number = 13
print(Solution().isHappy(number))

25
leetcode_py/21.py Normal file
View File

@@ -0,0 +1,25 @@
# Merge Two Sorted Lists
# 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, list1: ListNode, list2: ListNode):
prehead = ListNode(-1)
prev = prehead
while list1 and list2:
if list1.val <= list2.val:
prev.next = list1
list1 = list1.next
else:
prev.next = list2
list2 = list2.next
prev = prev.next
return prehead.next

16
leetcode_py/26.py Normal file
View File

@@ -0,0 +1,16 @@
# Remove Duplicates from Sorted Array
# -100 <= nums[i] <= 100
class Solution:
def removeDuplicates(self, nums: list[int]) -> int:
count = 0
if not nums:
return count
k = 1
for i in range(1, len(nums)):
if nums[i] != nums[i - 1]:
nums[k] = nums[i]
k += 1
return k

16
leetcode_py/263.py Normal file
View File

@@ -0,0 +1,16 @@
# Ugly number
# If positive number n has prime factors limited to 2, 3 and 5,
# it's a ugly prime
# -2^31 <= n <= 2^31 - 1
class Solution:
def isUgly(self, n: int) -> bool:
if n <= 0:
return False
for p in [2, 3, 5]:
while n % p == 0:
n = n // p
return n == 1

28
leetcode_py/27.py Normal file
View File

@@ -0,0 +1,28 @@
from typing import List
'''
Given an integer array nums and an integer val, remove all occurrences of val in nums in-place.
The order of the elements may be changed.
Then return the number of elements in nums which are not equal to val.
Consider the number of elements in nums which are not equal to val be k,
to get accepted, you need to do the following things:
Change the array nums such that the first k elements of nums
contain the elements which are not equal to val.
The remaining elements of nums are not important as well as the size of nums.
Return k.
Constraints:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
'''
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
k = len(nums)
while val in nums:
nums.remove(val)
k = k - 1
return k

12
leetcode_py/28.py Normal file
View File

@@ -0,0 +1,12 @@
"""
Given two strings needle and haystack,
return the index of the first occurrence of needle in haystack,
or -1 if needle is not part of haystack.
"""
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if needle in haystack:
return haystack.find(needle)
else:
return -1

14
leetcode_py/338.py Normal file
View File

@@ -0,0 +1,14 @@
# 338. Counting Bits
# Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n),
# ans[i] is the number of 1's in the binary representation of i.
class Solution:
def countBits(self, n: int) -> list[int]:
ans = []
for i in range(n + 1):
ans.append(bin(i).count("1"))
return ans
if __name__ == "__main__":
n = 5
print(Solution().countBits(n))

31
leetcode_py/35.py Normal file
View File

@@ -0,0 +1,31 @@
"""
Given a sorted array of distinct integers and a target value,
return the index if the target is found.
If not, return the index where it would be if it were inserted in order.
You must write an algorithm with O(log n) runtime complexity.
Constraints:
1 <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4
nums contains distinct values sorted in ascending order.
-10^4 <= target <= 10^4
"""
from typing import List
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
low = 0
high = len(nums) - 1
while low <= high: # Changed the condition to low <= high
mid = (high + low) // 2
if target == nums[mid]:
return mid
elif target < nums[mid]:
high = mid - 1
else:
low = mid + 1
return low

23
leetcode_py/36.py Normal file
View File

@@ -0,0 +1,23 @@
# Valid Sudoku
class Solution:
def isValidSudoku(self, board: list[list[int]]) -> bool:
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [set() for _ in range(9)]
for i in range(9):
for j in range(9):
num = board[i][j]
if num != ".":
box_index = (i // 3) * 3 + j // 3
if num in rows[i] or num in cols[j] or num in boxes[box_index]:
return False
rows[i].add(num)
cols[j].add(num)
boxes[box_index].add(num)
return True

37
leetcode_py/37.py Normal file
View File

@@ -0,0 +1,37 @@
# Sudoku Solver
class Solution:
def solveSudoku(self, board: list[list[int]]) -> None:
def isValid(board, row, col, num):
# Check if the number is in the current row
for x in range(9):
if board[row][x] == num:
return False
if board[x][col] == num:
return False
startRow, startCol = 3 * (row // 3), 3 * (col // 3)
for i in range(3):
for j in range(3):
if board[startRow + i][startCol + j] == num:
return False
return True
def solve(board):
for i in range(9):
for j in range(9):
if broad[i][j] == ".":
# Try all numbers for empty cell
for num in map(str, range(1, 10)):
if isValid(board, i, j, num):
board[i][j] = num
if solve(board):
return True
board[i][j] = "."
return False
return False
solve(board)

5
leetcode_py/461.py Normal file
View File

@@ -0,0 +1,5 @@
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
x_y = x ^ y
distance = bin(x_y)[2:].count("1")
return distance

12
leetcode_py/48.py Normal file
View File

@@ -0,0 +1,12 @@
# Rotate image
class Solution:
def rotate(self, matrix: list[list[int]]) -> None:
n = len(matrix)
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
for i in range(n):
matrix[i].reverse()

11
leetcode_py/58.py Normal file
View File

@@ -0,0 +1,11 @@
"""
Given a string s consisting of words and spaces,
return the length of the last word in the string.
A word is a maximal substring consisting of non-space characters only.
"""
class Solution:
def lengthOfLastWord(self, s: str) -> int:
s = s.strip()
s = s.split(" ")
return len(s[-1])

26
leetcode_py/645.py Normal file
View File

@@ -0,0 +1,26 @@
from typing import List
class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
sumSetNums = sum(set(nums))
sumNums = sum(nums)
return [sumNums - sumSetNums, ((len(nums) * (len(nums) + 1)) // 2) - sumSetNums]
def findErrorNums1(self, nums: List[int]) -> List[int]:
n = len(nums)
return_list = [0, 0]
for i in range(1, n + 1):
if i not in nums:
return_list[1] = i
break
for i in range(1, n + 1):
if i in nums:
nums.remove(i)
if i in nums:
return_list[0] = i
break
return return_list

45
leetcode_py/657.py Normal file
View File

@@ -0,0 +1,45 @@
# There is a robot starting at the position (0, 0), the origin,
# on a 2D plane. Given a sequence of its moves,
# judge if this robot ends up at (0, 0) after it completes its moves.
# You are given a string moves that represents
# the move sequence of the robot where moves[i]
# represents its ith move. Valid moves are 'R' (right),
# 'L' (left), 'U' (up), and 'D' (down).
# Return true if the robot returns to the origin after it finishes all of its moves,
# or false otherwise.
# Note: The way that the robot is "facing" is irrelevant.
# 'R' will always make the robot move to the right once,
# 'L' will always make it move left, etc. Also,
# assume that the magnitude of the robot's movement is the same for each move.
# Constraints:
# 1 <= moves.length <= 2 * 10^4
# moves only contains the characters 'U', 'D', 'L' and 'R'.
class Solution:
def judgeCircle1(self, moves: str) -> bool:
horizontal = 0
vertical = 0
for move in moves:
if move == "U":
vertical += 1
if move == "D":
vertical -= 1
if move == "L":
horizontal -= 1
if move == "R":
horizontal += 1
return horizontal == 0 and vertical == 0
def judgeCircle(self, moves: str) -> bool:
if moves.count("U")!=moves.count("D"):
return False
if moves.count("L")!=moves.count("R"):
return False
return True

22
leetcode_py/66.py Normal file
View File

@@ -0,0 +1,22 @@
"""You are given a large integer represented as an integer array digits,
where each digits[i] is the ith digit of the integer.
The digits are ordered from most significant to least significant in left-to-right order.
The large integer does not contain any leading 0's.
"""
from typing import List
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
n = len(digits)
# Start from the rightmost digit
for i in range(n - 1, -1, -1):
# If the current digit is less than 9, just increment it by 1 and return
if digits[i] < 9:
digits[i] += 1
return digits
# Otherwise, set the current digit to 0 and continue with the next digit
else:
digits[i] = 0
# If we reach here, it means all digits were 9, so we need to add a new leading 1
digits.insert(0, 1)
return digits

9
leetcode_py/67.py Normal file
View File

@@ -0,0 +1,9 @@
# Given two binary strings a and b, return their sum as a binary string.
class Solution:
def addBinary(self, a: str, b: str) -> str:
int_a = int("0b" + a, 2)
int_b = int("0b" + b, 2)
int_c = int_a + int_b
return bin(int_c)[2:]

28
leetcode_py/69.py Normal file
View File

@@ -0,0 +1,28 @@
# Sqrt(x)
# Do not use build in operator
class Solution:
def mySqrt(self, c: int) -> int:
# Use Newton's method, return the smaller root
# fx = x ** 2 - c
# Xn-1 = 0.5 * (Xn + c / Xn)
if c == 0:
return 0
if c == 1:
return 1
x = c / 2
while True:
next_x = (x + c / x) / 2
if x - next_x > -1 and x - next_x <= 0:
break
x = next_x
return int(x)
if __name__ == "__main__":
print(Solution().mySqrt(13))
print(Solution().mySqrt(16))

19
leetcode_py/7.py Normal file
View File

@@ -0,0 +1,19 @@
# Reverse Integer
class Solution:
def reverse(self, x: int) -> int:
str_x = str(x)
reverse_str_x = str_x[::-1]
if reverse_str_x[-1] == "-":
reverse_str_x = "-" + reverse_str_x[:-1]
return_x = int(reverse_str_x)
return return_x if return_x <= 2**31 - 1 and return_x >= -(2**31) else 0
if __name__ == "__main__":
x = 120
rev_x = Solution().reverse(x)
print(rev_x)
x = -123
print(Solution().reverse(x))

46
leetcode_py/70.py Normal file
View File

@@ -0,0 +1,46 @@
# Climbing Stairs
class Solution:
def climbStairs(self, n: int) -> int:
"""
# Fibonacci sequence
# too slow: O(n)
if n <= 2:
return n
first, second = 1, 2
for _ in range(3, n + 1):
first, second = second, first + second
return second
"""
# DP recurion
# fastest
from functools import cache
@cache
def f(n):
if n <= 2:
return n
return f(n - 1) + f(n - 2)
return f(n)
"""
# Matrix Power Solution
# O(log n) but slower???
if n <= 2:
return n
import numpy as np
M = np.array([[1, 1], [1, 0]])
A = np.array([[1, 1]]) @ np.linalg.matrix_power(M, n - 2) @ np.array([[1], [1]])
return A[0, 0]
"""
if __name__ == "__main__":
print(Solution().climbStairs(91))

23
leetcode_py/83.py Normal file
View File

@@ -0,0 +1,23 @@
# Given the head of a sorted linked list,
# delete all duplicates such that each element appears only once.
# Return the linked list sorted as well.
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
from typing import Optional
class Solution:
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head is None:
return head
pointer = head
while pointer.next is not None:
if pointer.val == pointer.next.val:
pointer.next = pointer.next.next
else:
pointer = pointer.next
return head

37
leetcode_py/88.py Normal file
View File

@@ -0,0 +1,37 @@
# You are given two integer arrays nums1 and nums2,
# sorted in non-decreasing order,
# and two integers m and n,
# representing the number of elements in nums1 and nums2 respectively.
# Merge nums1 and nums2 into a single array sorted in non-decreasing order.
# The final sorted array should not be returned by the function,
# but instead be stored inside the array nums1.
# To accommodate this, nums1 has a length of m + n,
# where the first m elements denote the elements that should be merged,
# and the last n elements are set to 0 and should be ignored. nums2 has a length of n.
# Constraints:
# nums1.length == m + n
# nums2.length == n
# 0 <= m, n <= 200
# 1 <= m + n <= 200
# -10^9 <= nums1[i], nums2[j] <= 10^9
from typing import List
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
if n == 0:
pass
else:
for i in range(n):
nums1[m+i] = nums2[i]
nums1.sort()

11
leetcode_py/9.py Normal file
View File

@@ -0,0 +1,11 @@
# Given an integer, return true if x is a palindrome
class Solution:
def isPalindrome(self, x: int) -> bool:
if x < 0:
return False
str_x = str(x)
inv_str_x = str_x[::-1]
int_inv_str_x = int(inv_str_x)
return x == int_inv_str_x

25
leetcode_py/94.py Normal file
View File

@@ -0,0 +1,25 @@
from typing import List, Optional
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return []
if root.left is not None:
return (
self.inorderTraversal(root.left)
+ [root.val]
+ self.inorderTraversal(root.right)
)
elif root.right is not None:
return [root.val] + self.inorderTraversal(root.right)
else:
return [root.val]