## leetcode刷題記錄
### 不做筆記的簡單題
[2535\. Difference Between Element Sum and Digit Sum of an Array](https://leetcode.com/problems/difference-between-element-sum-and-digit-sum-of-an-array/)
[2540\. Minimum Common Value](https://leetcode.com/problems/minimum-common-value/)
[2544\. Alternating Digit Sum](https://leetcode.com/problems/alternating-digit-sum/)
[2549\. Count Distinct Numbers on Board](https://leetcode.com/problems/count-distinct-numbers-on-board/)
[2582\. Pass the Pillow](https://leetcode.com/problems/pass-the-pillow/)
---
#### [482\. License Key Formatting](https://leetcode.com/problems/license-key-formatting/)
- 題目解釋
將licens進行重新排序,並使用分隔符號分隔,每個分隔階段只能有k個字母,唯獨第一段不受限制(僅需大於1即可),輸出需將所有字串字母轉為大寫。
- 解題思路
需要分隔,直接聯想split,第一個可以不用滿足k,所以可以採用倒敘方式進行字串加法。
- 程式碼
```python=0
class Solution:
def licenseKeyFormatting(self, s: str, k: int) -> str:
t = s.split("-")
t = ''.join(t) #進行合併 -> 5F3Z2e9w
count = 0
ans = []
for i in range(len(t)-1,-1,-1):
count += 1
if(count%k==0):
ans.append(t[-k:])
ans.append("-")
t = t[:-k]
if(len(t)<k):
ans.append(t)
break
ans = ans[::-1]
ans = ''.join(ans)
if(len(ans)!=0 and ans[0]=="-"):
return ans[1:].upper()
return ans.upper()
```
- 遇到問題
1. 因為不之原因測資修改,而跑出錯誤(明明預期跟output一樣),後續查看discussion也有同樣問題,說明只要重置測資就可以。
2. 會有"---"、k=3的測資出現,此為輸出""即可(但題目沒有詳細說明,且測試時會一直卡住不過。
- 新學習
可以使用upper()或lower()將字串轉為大小寫
- 時間複雜度
- 空間複雜度
---
#### [495\. Teemo Attacking](https://leetcode.com/problems/teemo-attacking/)
- 題目解釋
攻擊方會每隔幾秒進行攻擊,被攻擊者則會持續幾秒中毒,最終要計算出被攻擊者中毒的時間。
- 解題思路
從測資來看會發現,如果攻擊間距小於攻擊發動的間隔,那被攻擊者中毒的秒數就會變少,所以從這點來看我們可以找出重疊的時間在哪,利用max方式進行找尋,如果不再範圍內那就用list進行記錄。
- 程式碼
```python=1
class Solution:
def findPoisonedDuration(self, timeSeries: List[int], duration: int) -> int:
a = []
l = timeSeries[0]
r = l + duration
for i in range(1,len(timeSeries)):
if(timeSeries[i]<=r):
r = max(timeSeries[i] + duration,r)
elif(timeSeries[i] > r):
a.append([l,r])
l = timeSeries[i]
r = l + duration
total = 0
a.append([l,r])
for [k,v] in a:
total += (v-k)
return total
```
#### [682\. Baseball Game](https://leetcode.com/problems/baseball-game/)
- 題目解釋
主要會遇到四種類型輸入,分別有+、D、C以及數字,這些都是使用字串進行存取,遇到數字要把數字放入陣列,遇到加號需要把最後兩位數字相加放入陣列,遇到D需要把最後一位乘上二放入陣列,最後遇到C則是把陣列中最後一位數字進行移除。
- 解題思路
遇到需要最後一位的數字,可使用陣列的pop()方式,將最後一位取出進行動作。
- 程式碼
```python=1
class Solution:
def calPoints(self, operations: List[str]) -> int:
ans = 0
stack = []
for i in range(len(operations)):
if(operations[i] == "+"):
temp = stack.pop()
temp2 = stack.pop()
stack.append(temp2)
stack.append(temp)
stack.append(temp + temp2)
elif(operations[i] == "D"):
temp = stack.pop()
stack.append(temp)
stack.append(temp * 2)
elif(operations[i] == "C"):
stack.pop()
else:
stack.append(int(operations[i]))
for i in range(len(stack)):
ans += stack[i]
return ans
```
- 遇到問題
原以為需要考量stack長度問題,但題目中已說明會確保這些問題不存在,因此沒多做考量。
- 新學習
無
- 時間複雜度
- 空間複雜度
#### [338\. Counting Bits](https://leetcode.com/problems/counting-bits/)
- 題目解釋
給定一個十進位數字n,將0~n轉換為二進位,並計算出二進位後的1佔有幾位。
- 解題思路
轉換為二進位直接使用bin(),計算特定出現的字元,可用count()進行計算。
- 程式碼
```python=1
class Solution:
def countBits(self, n: int) -> List[int]:
ans = []
for i in range(0,n+1):
ans.append(bin(i).count("1"))
return ans
```
- 遇到問題
無
- 新學習
1. bin()所花的時間複雜度為O(log n)
https://stackoverflow.com/questions/50793388/time-complexity-of-bin-in-python
https://github.com/python/cpython/blob/6405feecda6a5d5dd7a4240eb3054a2676ed29b1/Objects/longobject.c#L1851
2. count()所花的時間複雜度為O(n)
https://stackoverflow.com/questions/44812468/what-is-the-time-complexity-of-python-lists-count-function
- 時間複雜度
- 空間複雜度
[455\. Assign Cookies](https://leetcode.com/problems/assign-cookies/)
- 題目解釋
- 解題思路
- 程式碼
- 遇到問題
- 新學習
- 時間複雜度
- 空間複雜度
[338\. Counting Bits](https://leetcode.com/problems/counting-bits/)
- 題目解釋
計算出重複次數最多的數字的子集,例如[1,2,3,1,1],1出現次數最多,那找出陣列中最小的子集,這個子集要能包含三個1,所以就會是選擇最前面跟最後面為[1,2,3,1,1],但如果今天測資是[1,2,2,2,1,1],1跟2出現同樣次數,那就找他們最小子集能夠包含1或是能夠包含2,所以答案會是[2,2,2],最後輸出子集長度。
- 解題思路
首先是要找出出現次數,所以選用python提供的collections的Counter,他會直接輸出每一個元素出現的數字,但也能改用dict()迭代進行計算。
接著,是找出最小子集,所以可以觀察到只要計算出出現次數最頻繁的頭尾index,就能記錄出最小子集的長度為何。
- 程式碼
```python=1
from collections import Counter
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
x = Counter(nums)
a = dict()
b = dict()
for i in range(len(nums)):
if(a.get(nums[i])==None):
a[nums[i]]=i
for i in range(len(nums)-1,-1,-1):
if(b.get(nums[i])==None):
b[nums[i]]=i
large = 0
ans = float('inf')
x_sort= sorted(x.items(),key= lambda kv:kv[1],reverse=True)
for (k,v) in x_sort:
if(v>=large):
large = v
temp = b[k]-a[k] + 1
if(temp<ans):
ans = temp
else:
break
return ans
```
- 遇到問題
主要是需要思路清晰,很容易忽視其中需要的步驟。
- 新學習
無
- 時間複雜度
- 空間複雜度
#### [1828\. Queries on Number of Points Inside a Circle](https://leetcode.com/problems/queries-on-number-of-points-inside-a-circle/)
- 題目解釋
給定點的位置,以及給定圓心位置與圓的半徑大小,最後判斷每個圓裡面有多少個點。
- 解題思路
想到有個數學定理能夠解決這問題,此為勾股定理,(x1-x2)^2+(y1-y2)^2<r^2,x2跟y2為圓心,小於為圓內,等於為邊上。以此下去解題。
- 程式碼
```python=1
class Solution:
def countPoints(self, points: List[List[int]], queries: List[List[int]]) -> List[int]:
# (x1-x2)^2+(y1-y2)^2<r^2,x2跟y2為圓心,小於為圓內,等於為邊上
ans = []
for x2,y2,r in queries:
total = 0
for x1,y1 in points:
if(((x1-x2)**2 + (y1-y2)**2)<= r**2):
total += 1
ans.append(total)
return ans
```
- 遇到問題
無
- 新學習
學習不要C style進行解題
- 時間複雜度
- 空間複雜度
#### [1329\. Sort the Matrix Diagonally](https://leetcode.com/problems/sort-the-matrix-diagonally/)
- 題目解釋
把陣列依照對角線進行排序
- 解題思路
可以知道對角線的座標相減為同個數字,那只需要把數字記錄下來,進行後續排序即可,接著,在進行讀取放入回陣列中。
- 程式碼
```python=1
class Solution:
def diagonalSort(self, mat: List[List[int]]) -> List[List[int]]:
a = defaultdict(list)
for i in range(len(mat)):
for j in range(len(mat[i])):
a[i-j].append(mat[i][j])
for i in a:
a[i].sort(reverse=True)
for i in range(len(mat)):
for j in range(len(mat[i])):
mat[i][j] = a[i-j].pop()
return mat
```
- 遇到問題
用想的很簡單,但實際上該如何把list用在dict中,後來找到原來defaultdict(list)可以進行使用,這樣就能在dict讀取時進行排序。
- 新學習
defaultdict(list)
- 時間複雜度
- 空間複雜度
#### [2433\. Find The Original Array of Prefix Xor](https://leetcode.com/problems/find-the-original-array-of-prefix-xor/)
- 題目解釋
已知前一個list的XOR prefix sum,那要如何知道原本的list?
- 解題思路
了解xor特性,5^7=2、5^2=7、2^7=5,看題目會知道例如list_xor=[5,2,7,3,1],那5是原本跟0的xor數字可以先跳過,接著看2,2為5^x=2,所以x為7,接著7為2^x=7,所以x為5,再來3為7^x=3,x=4,以此類推,得出[5,7,5,4,2]
- 程式碼
```python=1
class Solution:
def findArray(self, pref: List[int]) -> List[int]:
ans = [pref[0]]
if(len(pref)==1):
return ans
for i in range(1,len(pref)):
ans.append(pref[i-1]^pref[i])
return ans
```
- 遇到問題
有觀察到這個特性,但不太確定原因,所以寫了一下數學算式即可得知。
- 時間複雜度
- 空間複雜度
#### [1652\. Defuse the Bomb](https://leetcode.com/problems/defuse-the-bomb/)
- 題目解釋
給定list跟k,輸出前k個大小(k<0),輸出list後k個大小(k>0)。
- 解題思路
因為每個list位置都得計算一次,所以一定會走遍整個list,因此我們可以先算出每k個的sum,算完之後在找出k會從哪個位置開始,進行輸出。
- 程式碼
```python=1
class Solution:
def decrypt(self, code: List[int], k: int) -> List[int]:
if(k == 0):
return [0] * len(code)
ans = []
count = abs(k)
for i in range(len(code)):
if (i+count) < len(code):
ans.append(sum(code[i:i+count]))
else:
ans.append(sum(code[i:len(code)])+sum(code[0:count-(len(code)-i)]))
if(k > 0):
ans.append(ans[0])
return ans[1:len(ans)]
elif(k < 0):
return ans[k:len(ans)]+ans[0:len(ans)+k]
```
- 新學習
不確定sum可不可以進行陣列計算,查詢之後是可以,以及花費的複雜度為O(n),其中n的大小取決於所需要統計的陣列大小。
- 時間複雜度
O(N)
- 空間複雜度
O(N)
#### [1694\. Reformat Phone Number](https://leetcode.com/problems/reformat-phone-number/)
- 題目解釋
給定一串字串,裡面包含"-" 及" ",依照電話號碼數量進行分隔。
- 解題思路
先將"-"以及" "去除,接著依照固定格式進行判斷並加上分隔符號即可。
- 程式碼
```python=1
class Solution:
def reformatNumber(self, number: str) -> str:
ans = []
new_number = []
for i in number:
if(i != "-" and i != " "):
new_number.append(i)
new_number = "".join(new_number)
count = len(new_number)
i = 0
while(count > 4):
ans.append(new_number[i:i+3])
ans.append("-")
i = i + 3
count = count - 3
if(count == 0):
ans = ans[:-1]
elif(count == 1):
ans.append(new_number[i])
elif(count == 2):
ans.append(new_number[i:i+2])
elif(count == 3):
ans.append(new_number[i:i+3])
elif(count == 4):
ans.append(new_number[i:i+2])
ans.append("-")
ans.append(new_number[i+2:i+4])
ans_str = "".join(ans)
return ans_str
```
- 遇到問題
- 新學習
要注意split不能連用兩次,因為第二次已經是list了,複雜度為O(N)。
- 時間複雜度
O(N)
- 空間複雜度
O(N)
#### [113\. Path Sum II](https://leetcode.com/problems/path-sum-ii/)
- 題目解釋
DFS相關
- 解題思路
- 程式碼
```python=1
# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
res = []
def dfs(root,path,num):
if(root == None):
return
num = num + root.val
if(root.left == None and root.right==None and num == targetSum):
res.append(path+[root.val])
if(root.left == None and root.right!=None):
dfs(root.right,path+[root.val],num)
if(root.left != None and root.right==None):
dfs(root.left,path+[root.val],num)
if(root.left != None and root.right!=None):
dfs(root.left,path+[root.val],num)
dfs(root.right,path+[root.val],num)
dfs(root,[],0)
return res
```
- 遇到問題
- 新學習
- 時間複雜度
- 空間複雜度
#### [199\. Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/)
- 題目解釋
BFS
- 程式碼
```python=1
# 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
import queue
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
ans = []
if(not root):
return ans
q = queue.Queue()
q.put(root)
while(q.qsize()):
l = q.qsize()
for i in range(l):
x = q.get()
if(x.left):
q.put(x.left)
if(x.right):
q.put(x.right)
if(i == (l-1)):
ans.append(x.val)
return ans
```
#### [230\. Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)
- 題目解釋
中序遍歷(inorder)
- 程式碼
```python=1
# 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 kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
a = []
def dfs(root):
if(root.left):
dfs(root.left)
a.append(root.val)
if(root.right):
dfs(root.right)
dfs(root)
return a[k-1]
```
#### [96\. Unique Binary Search Trees](https://leetcode.com/problems/unique-binary-search-trees/)
卡特蘭數
- 解題思路
1,1,2,5,14,42,,,,
```python=1
class Solution:
def numTrees(self, n: int) -> int:
#catalan c2n取n/(n+1)=>c10取5/6
mosum = 1
sonsum = 1
for i in range(2*n,n,-1):
mosum *= i
for i in range(n,0,-1):
sonsum *= i
return int(int(mosum/sonsum)/int(n+1))
```
#### [171\. Excel Sheet Column Number](https://leetcode.com/problems/excel-sheet-column-number/)
- 題目解釋
計算出excel是第幾個column
- 解題思路
直接從後面倒數,然後看是第幾個就乘幾次26
- 程式碼
```python=1
class Solution:
def titleToNumber(self, s: str) -> int:
ans = 0
for i in range(len(s)-1,-1,-1):
ans = ans + (ord(s[i])-64)*(26**(len(s)-1-i))
return ans
```
#### [168\. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/)
- 題目解釋
上一題倒過來解,但是要注意%之後會少一
- 解題思路
- 程式碼
```python=1
class Solution:
def convertToTitle(self, columnNumber: int) -> str:
s = []
while(columnNumber!=0):
n = columnNumber%26
if(n == 0):
columnNumber = (columnNumber-26) / 26
else:
columnNumber = (columnNumber-n) / 26
if(n == 0):
s.append("Z")
else:
s.append(chr(int(n)+64))
s = "".join(s[::-1])
return s
```
#### [628\. Maximum Product of Three Numbers](https://leetcode.com/problems/maximum-product-of-three-numbers/)
- 題目解釋
- 解題思路
用貪婪演算法,直接找出可能的最大值
- 程式碼
```python=1
class Solution:
def maximumProduct(self, nums: List[int]) -> int:
if(len(nums)==3):
return nums[0]*nums[1]*nums[2]
nums.sort()
n = len(nums)
return max(nums[n-1] * nums[n-2] * nums[n-3], nums[0] * nums[1] * nums[n-1])
```
#### [654\. Maximum Binary Tree](https://leetcode.com/problems/maximum-binary-tree/)
- 題目解釋
給定list建構binary tree
- 解題思路
- 程式碼
```python=1
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if(len(nums)==0):
return
def dfs(nums):
if(len(nums)==0):
return
mx = max(nums)
mxi = nums.index(mx)
a = TreeNode(mx)
a.left=dfs(nums[:mxi])
a.right=dfs(nums[mxi+1:])
return a
return dfs(nums)
```
#### [796\. Rotate String](https://leetcode.com/problems/rotate-string/)
- 題目解釋
- 解題思路
旋轉題目一律先想到將目標進行相加
- 程式碼
```python=1
class Solution:
def rotateString(self, s: str, goal: str) -> bool:
if(len(s)==len(goal) and goal in (s+s)):
return 1
return 0
```
#### [606\. Construct String from Binary Tree](https://leetcode.com/problems/construct-string-from-binary-tree/)
- 題目解釋
給定一個tree,根據輸入的部分輸出括號
- 解題思路
直接聯想到dfs,並在每個遞迴前用括號包住
- 程式碼
```python=1
# 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 tree2str(self, root: Optional[TreeNode]) -> str:
ans = []
def dfs(root):
if(root == None):
ans.append("()")
ans.append(str(root.val))
if(root.left==None and root.right):
ans.append("()")
if(root.left):
ans.append("(")
dfs(root.left)
ans.append(")")
if(root.right):
ans.append("(")
dfs(root.right)
ans.append(")")
dfs(root)
s = "".join(ans)
return s
```
#### [872\. Leaf-Similar Trees](https://leetcode.com/problems/leaf-similar-trees/)
- 題目解釋
對比兩棵樹的葉子,查看數字是否一樣
- 解題思路
直接使用dfs紀錄兩邊葉子
- 程式碼
```python=1
# 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 leafSimilar(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool:
ans = []
ans2 = []
def dfs(root):
if(root==None):
return
if(root.right == None and root.left == None):
ans.append(root.val)
if(root.right):
dfs(root.right)
if(root.left):
dfs(root.left)
def dfs2(root):
if(root==None):
return
if(root.right == None and root.left == None):
ans2.append(root.val)
if(root.right):
dfs2(root.right)
if(root.left):
dfs2(root.left)
dfs(root1)
dfs2(root2)
return ans==ans2
```
#### [965\. Univalued Binary Tree](https://leetcode.com/problems/univalued-binary-tree/)
- 題目解釋
找出是否有不一樣的數字存在tree中
- 解題思路
直接使用dfs紀錄所有節點
- 程式碼
```python=1
# 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 isUnivalTree(self, root: Optional[TreeNode]) -> bool:
ans = []
def dfs(root):
if(root==None):
return
ans.append(root.val)
if(root.left):
dfs(root.left)
if(root.right):
dfs(root.right)
dfs(root)
for i in range(1,len(ans)):
if(ans[0]!=ans[i]):
return False
return True
```
#### [1022\. Sum of Root To Leaf Binary Numbers](https://leetcode.com/problems/sum-of-root-to-leaf-binary-numbers/)
#### [108\. Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/)
- 題目解釋
給定sorting array建立出BST
- 解題思路
直接使用遞迴方式建樹,並從中找出每個array出現時的中間數
- 程式碼
```python=1
# 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 sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
r = len(nums)-1
l = 0
def con(num,l,r):
if(l>r):
return None
medi = int((r-l)/2) + l
root = TreeNode(num[medi])
root.left = con(num,l,medi-1)
root.right = con(num,medi+1,r)
return root
return con(nums,l,r)
```
#### [173\. Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/)
- 題目解釋
將inorder寫成class形式
- 解題思路
先找出inoder的array,接著直接用array判斷即可
- 程式碼
```python=1
# 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 BSTIterator:
def __init__(self, root: Optional[TreeNode]):
self.root = root
self.ans = []
def dfs(root):
if(root.left):
dfs(root.left)
self.ans.append(root.val)
if(root.right):
dfs(root.right)
dfs(self.root)
def next(self) -> int:
if(len(self.ans)!=0):
a = self.ans[0]
self.ans = self.ans[1:]
return a
def hasNext(self) -> bool:
if(len(self.ans)!=0):
return True
else:
return False
# Your BSTIterator object will be instantiated and called as such:
# obj = BSTIterator(root)
# param_1 = obj.next()
# param_2 = obj.hasNext()
```
#### [341\. Flatten Nested List Iterator](https://leetcode.com/problems/flatten-nested-list-iterator/)
#### [637\. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/)
- 題目解釋
計算每一層的節點數值並輸出平均
- 解題思路
直接使用bfs進行遍歷
- 程式碼
```python=1
# 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
import queue
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
q = queue.Queue()
q.put(root)
ans = []
while(q.qsize()):
temp = 0
n = 0
l = q.qsize()
for i in range(l):
x = q.get()
if(x.right):
q.put(x.right)
if(x.left):
q.put(x.left)
temp += x.val
n += 1
ans.append(temp / n)
return ans
```
#### [623\. Add One Row to Tree](https://leetcode.com/problems/add-one-row-to-tree/)
- 題目解釋
給定val跟depth並從中插入至tree中
- 解題思路
使用level travelsal 進行判斷與插入,但要注意有例外,如果當插入的為根節點,那原先節點要插入至左邊。
- 程式碼
```python=1
# 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
import queue
class Solution:
def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:
if(depth == 1):
x = TreeNode(val)
x.left = root
return x
q = queue.Queue()
q.put(root)
n = 1
while(q.qsize()):
l = q.qsize()
n += 1
for i in range(l):
x = q.get()
if(n == depth):
if(x.left):
temp = x.left
x.left = TreeNode(val)
x.left.left = temp
else:
print(x.val)
x.left = TreeNode(val)
if(x.right):
temp = x.right
x.right = TreeNode(val)
x.right.right = temp
else:
x.right = TreeNode(val)
else:
if(x.left):
q.put(x.left)
if(x.right):
q.put(x.right)
return root
```
#### [143\. Reorder List](https://leetcode.com/problems/reorder-list/)
- 題目解釋
照題目意思將linkedlist位置進行變換
- 解題思路
找出規律,會發現是把arr中的內容最後面->最前面->最後面...等於是實作一個array把前後元素拿出來替換。
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reorderList(self, head: Optional[ListNode]) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if(head.next == None):
return
a = []
pre = head
aft = head.next
while(pre):
a.append(pre.val)
pre = pre.next
a = a[1:]
n = 1
while(aft):
if(n%2==0):
aft.val = a[0]
if(len(a)>1):
a = a[1:]
else:
aft.val = a.pop()
aft = aft.next
n += 1
```
#### [225\. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/)
- 題目解釋
實作stack
- 解題思路
實作stack
- 程式碼
```python=1
class MyStack:
def __init__(self):
self.stac = []
def push(self, x: int) -> None:
self.stac.append(x)
def pop(self) -> int:
r = self.stac[-1]
self.stac = self.stac[:-1]
return r
def top(self) -> int:
return self.stac[-1]
def empty(self) -> bool:
if(len(self.stac)==0):
return True
return False
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()
```
#### [921\. Minimum Add to Make Parentheses Valid](https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/)
- 題目解釋
判斷如果要達成符合規則的括號,最小需添加的次數
- 解題思路
直接使用stack進行判斷,如果遇到右括號,前面一個是左括號直接pop掉
- 程式碼
```python=1
class Solution:
def minAddToMakeValid(self, s: str) -> int:
a = []
for i in s :
if(len(a)!= 0):
x = a.pop()
if(i == ")" and x=="("):
pass
else:
a.append(x)
a.append(i)
else:
a.append(i)
return len(a)
```
#### [856\. Score of Parentheses](https://leetcode.com/problems/score-of-parentheses/)
- 題目解釋
需依照題目給的規則下去計算括弧中最後得出的分數
- 解題思路
使用Stack進行判斷,如果前一個為數字則相加之後如果為"("則進行乘2,如果一開始則遇到括弧直接放入數字1,最後再計算陣列中的總合。
- 程式碼
```python=1
class Solution:
def scoreOfParentheses(self, s: str) -> int:
stac = []
for i in s:
temp = 0
if(i == ")"):
x = stac[-1]
if(x=="("):
stac.pop()
stac.append(1)
else:
temp = 0
while(stac[-1]!="("):
x = stac.pop()
temp += x
stac.pop()
stac.append(temp*2)
elif(i == "("):
stac.append("(")
return sum(stac)
```
- 新學習
可以改用[-1]先查看stack的尾端,再決定要不要pop()
#### [1381\. Design a Stack With Increment Operation](https://leetcode.com/problems/design-a-stack-with-increment-operation/)
- 題目解釋
(實作題)依照題目定義實作出兩種基本stack操作,以及增加increment函式
- 解題思路
無
- 程式碼
```python=1
class CustomStack:
def __init__(self, maxSize: int):
self.stac = []
self.maxSize = maxSize
def push(self, x: int) -> None:
if(len(self.stac)<self.maxSize):
self.stac.append(x)
def pop(self) -> int:
if(len(self.stac)!=0):
ans = self.stac[-1]
self.stac = self.stac[:-1]
return ans
else:
return -1
def increment(self, k: int, val: int) -> None:
for i in range(0,min(k,len(self.stac))):
self.stac[i] += val
# Your CustomStack object will be instantiated and called as such:
# obj = CustomStack(maxSize)
# obj.push(x)
# param_2 = obj.pop()
# obj.increment(k,val)
```
#### [1441\. Build an Array With Stack Operations](https://leetcode.com/problems/build-an-array-with-stack-operations/)
- 題目解釋
給定一個target並且限制最大數量,看如何push跟pop能夠達到跟target一樣
- 解題思路
觀察法可以直接發現,當有遺漏的數字,即可加入push pop,如果沒有遺漏則是push
- 程式碼
```python=1
class Solution:
def buildArray(self, target: List[int], n: int) -> List[str]:
ans = []
num = 0
for i in range(1,min(n+1,target[-1]+1)):
if(target[num]==i):
ans.append("Push")
num+=1
else:
ans.append("Push")
ans.append("Pop")
return ans
```
#### [1544\. Make The String Great](https://leetcode.com/problems/make-the-string-great/)
- 題目解釋
如果相鄰的兩個字母為大小寫,則進行刪除
- 解題思路
直接使用stack解,遇到前一個為大小寫的直接pop掉
- 程式碼
```python=1
class Solution:
def makeGood(self, s: str) -> str:
stac = []
for i in s:
if(len(stac)== 0):
stac.append(i)
else:
if(abs(ord(stac[-1])-ord(i))==32):
stac.pop()
else:
stac.append(i)
stac = "".join(stac)
return stac
```
#### [2903\. Find Indices With Index and Value Difference I](https://leetcode.com/problems/find-indices-with-index-and-value-difference-i/)
- 題目解釋
需要找出index與value相差值在規定範圍內的index
- 解題思路
直接照題目規定,使用雙迴圈進行解題,一一找出符合規範的值
- 程式碼
```python=1
class Solution:
def findIndices(self, nums: List[int], indexDifference: int, valueDifference: int) -> List[int]:
ans = []
for i in range(len(nums)):
for n in range(i + indexDifference,len(nums)):
if(n<len(nums)):
if(abs(nums[i]-nums[n])>=valueDifference):
ans.append(i)
ans.append(n)
if(len(ans)==0):
return [-1,-1]
return ans
```
#### [701\. Insert into a Binary Search Tree](https://leetcode.com/problems/insert-into-a-binary-search-tree/)
- 題目解釋
將題目給定val插入至bst當中
- 解題思路
直接往下遞迴檢查,如果發現為空則插入node
- 程式碼
```python=1
# 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 insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
def dfs(root,val):
if(root==None):
return TreeNode(val)
elif(val>root.val):
root.right = dfs(root.right,val)
elif(val<root.val):
root.left = dfs(root.left,val)
return root
return dfs(root,val)
```
#### [1266\. Minimum Time Visiting All Points](https://leetcode.com/problems/minimum-time-visiting-all-points/)-每日題目
- 題目解釋
找出到下一個points時需要多少步數能夠達到
- 解題思路
觀察法能夠看出只要找出相減後最大的值即為所需步數
- 程式碼
```python=1
class Solution:
def minTimeToVisitAllPoints(self, points: List[List[int]]) -> int:
total = 0
for i in range(1,len(points)):
total = total+max(abs(points[i][0]-points[i-1][0]),abs(points[i][1]-points[i-1][1]))
return total
```
#### [405\. Convert a Number to Hexadecimal](https://leetcode.com/problems/convert-a-number-to-hexadecimal/)
- 題目解釋
將十進位轉為十六進位
- 解題思路
包含負數,因此需要考量二補數,直接將補數先行加上負數進行計算
- 程式碼
```python=1
class Solution:
def toHex(self, num: int) -> str:
list_hex = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
ans = []
if(num<0):
x = 16**8
num = num + x
while(num>=16):
ans.append(list_hex[num%16])
num = num // 16
ans.append(list_hex[num])
ans = ans[::-1]
ans = "".join(ans)
return ans
```
####
- 題目解釋
分享餅乾,每個array代表因子,進行餅乾分配
- 解題思路
使用迴圈紀錄所在位置,遇到符合的將後退一格
- 程式碼
```python=1
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
i,j,ans = 0,0,0
g.sort()
s.sort()
while(j<len(s) and i<len(g)):
if(s[j]>=g[i]):
ans += 1
i += 1
j += 1
return ans
```
#### [830\. Positions of Large Groups](https://leetcode.com/problems/positions-of-large-groups/)
- 題目解釋
找出連續出現三次以上的字母位置起始點跟終點
- 解題思路
直接紀錄位置一一判斷
- 程式碼
```python=1
class Solution:
def largeGroupPositions(self, s: str) -> List[List[int]]:
start,end = 0,1
ans = []
while(end<len(s) and start<len(s)):
if(s[start]==s[end]):
end += 1
else:
if((end-start)>=3):
end -= 1
ans.append([start,end])
start = end
end += 1
if((end-start)>=3):
end -= 1
ans.append([start,end])
return ans
```
#### [824\. Goat Latin](https://leetcode.com/problems/goat-latin/)
- 題目解釋
將字串進行轉換,如果第一個字母為子音,則對調到最後一個字母,每一個字後面都要加上ma,並依照字串數量加上a
- 解題思路
判斷子音及母音,並且計算出現的數量,之後就是進行字串的程式撰寫
- 程式碼
```python=1
class Solution:
def toGoatLatin(self, sentence: str) -> str:
s = sentence.split(" ")
alpha = ["a","e","i","o","u","A","E","I","O","U"]
num = 1
space = " "
ans = []
for i in s:
num += 1
if(i[0] in alpha):
st = i+"m"+"a"*num
else:
st = i[1:]+i[0]+"m"+"a"*num
ans.append(st)
ans.append(space)
ans = "".join(ans[:-1])
return ans
```
#### [859\. Buddy Strings](https://leetcode.com/problems/buddy-strings/)
- 題目解釋
判斷字串裡交換過一次之後可以等於目標字串即回傳True
- 解題思路
一定得交換一次,而且只能交換一次,因此需要考量一些情況,包含如果今天字母都只出現一次,s=abc、goal=abc,代表不管交換哪個都沒辦法再度等於abc
- 程式碼
```python=1
class Solution:
def buddyStrings(self, s: str, g: str) -> bool:
index = []
a = dict()
flag = 0
if(len(s)!=len(g) or len(s)==1):
return False
for i in range(len(s)):
if(s[i] not in a):
a[s[i]] = 1
else:
a[s[i]] += 1
flag = 1
if(s[i]!=g[i]):
index.append(i)
if(flag == 0 and len(index)==0):
return False
if(len(index)==0 or (len(index)==2 and s[index[0]]==g[index[1]] and s[index[1]]==g[index[0]])):
return True
else:
return False
```
#### [563\. Binary Tree Tilt](https://leetcode.com/problems/binary-tree-tilt/)
- 題目解釋
將左右子樹的總節點值進行相減並回傳
- 解題思路
使用遞迴方式,將值回傳
- 程式碼
```python=1
# 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 findTilt(self, root: Optional[TreeNode]) -> int:
self.ans = 0
def dfs(root):
if(root==None):
return 0
left = dfs(root.left)
right = dfs(root.right)
self.ans += abs(left-right)
return left+right+root.val
dfs(root)
return self.ans
```
#### [598\. Range Addition II](https://leetcode.com/problems/range-addition-ii/)
- 題目解釋
給定矩陣大小,並給定後續需要陸續相加的矩陣位置,由內自外相加,最終回傳矩陣內最大值有幾個。
- 解題思路
找出重疊面積,也就是重疊的矩形,因為是由內到外,所以只需要紀錄每次最小的那個矩形即可,代表他重複最多次
- 程式碼
```python=1
class Solution:
def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int:
w = m
h = n
for i,j in ops:
w = min(i,w)
h = min(j,h)
return w*h
```
#### [1287\. Element Appearing More Than 25% In Sorted Array](https://leetcode.com/problems/element-appearing-more-than-25-in-sorted-array/)
- 題目解釋
找出陣列中出現超過25%的值(只有唯一解)
- 解題思路
題目說過array是排序過的,那就代表有25%的區間是同一個值,因此使用指針指向,間隔25%找到一樣的值就回傳。
- 程式碼
```python=1
class Solution:
def findSpecialInteger(self, arr: List[int]) -> int:
r = int(len(arr)//4)
l = 0
while(r<len(arr)):
if(arr[r]==arr[l]):
return arr[r]
r += 1
l += 1
return arr[r]
```
#### [541\. Reverse String II](https://leetcode.com/problems/reverse-string-ii/)
- 題目解釋
將固定數量的字串進行反轉
- 解題思路
直接使用python字串特性下去解題,並注意題目所說的條件
- 程式碼
```python=1
class Solution:
def reverseStr(self, s: str, k: int) -> str:
l = len(s)%(k)
temp = []
n = 1
for i in range(0,len(s)-l,k):
x = s[i:i+k]
if(n%2==1):
temp.append(x[::-1])
else:
temp.append(x)
n+=1
if(l<k):
x = s[len(s)-l:len(s)]
if(n%2==1):
temp.append(x[::-1])
else:
temp.append(x)
else:
x = s[-2*k:-l]
temp.append(x[::-1])
temp.append(s[l:-1])
ans = ''.join(temp)
return ans
```
#### [206\. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/)
- 題目解釋
反轉鏈結串列
- 解題思路
前中後節點進行儲存,並依序反轉
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = head
pre = None
post = None
while(cur):
post = cur.next
cur.next = pre
pre = cur
cur = post
return pre
```
#### [141\. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/)
- 題目解釋
查找鏈結串列是否有迴圈出現
- 解題思路
將節點數值往上加,發現超過原來範圍即為有迴圈出現
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
while(head):
if(head.val >= 500000):
return True
head.val += 700000
head = head.next
return False
```
####
- 題目解釋
判斷是否為有效的括號規則
- 解題思路
使用堆疊進行判斷,找出互相對應的括號,必須要注意會有單括號的出現,如果只有一個open最後得判斷stack數量,反之只有一個close則得判斷中間pop時的stack數量。
- 程式碼
```python=1
class Solution:
def isValid(self, s: str) -> bool:
stack = []
for i in s:
if(i == "(" or i == "[" or i == "{"):
stack.append(i)
else:
if(len(stack) == 0):
return False
if(stack[-1] == "(" and i ==")"):
stack.pop()
elif(stack[-1] == "[" and i =="]"):
stack.pop()
elif(stack[-1] == "{" and i =="}"):
stack.pop()
else:
return False
if(len(stack) != 0):
return False
return True
```
#### [1496\. Path Crossing](https://leetcode.com/problems/path-crossing/)
- 題目解釋
給定方位,並判斷是否會重複走到同一個點
- 解題思路
使用dict將東南西北進行紀錄,之後只需要使用set判斷是否為單一值即可
- 程式碼
```python=1
class Solution:
def isPathCrossing(self, path: str) -> bool:
dic = {"N":[0,1],"E":[1,0],"S":[0,-1],"W":[-1,0]}
cross = set()
dis = [0,0]
cross.add(tuple(dis))
for i in path:
dis[0] += dic[i][0]
dis[1] += dic[i][1]
if(tuple(dis) in cross):
return True
cross.add(tuple(dis))
return False
```
#### [92\. Reverse Linked List II](https://leetcode.com/problems/reverse-linked-list-ii/)
- 題目解釋
將Linked List進行範圍性的反轉並輸出
- 解題思路
用與Reverse Linked List I一樣的方式分成pre cur post,剩下僅需直接付值即可
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
pre = None
cur = head
post = None
count = 1
ans = ListNode(1)
x = ans
flag = 0
while(cur):
if(count >= left and count <= right):
post = cur.next
cur.next = pre
pre = cur
cur = post
else:
if(pre and flag == 0):
while(pre):
ans.next = pre
ans = ans.next
pre = pre.next
flag =1
else:
ans.next = cur
ans = ans.next
cur = cur.next
count += 1
if(pre and flag == 0):
while(pre):
ans.next = pre
ans = ans.next
pre = pre.next
return x.next
```
#### [61\. Rotate List](https://leetcode.com/problems/rotate-list/)
- 題目解釋
旋轉linkedlist
- 解題思路
第一個迴圈計算數量,第二個迴圈將後半部分先記錄,第三個回圈則是補齊數量
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if(not head or k == 0):
return head
temp = head
total = 0
while(temp):
temp = temp.next
total += 1
c = total - (k % total) + 1
if(total == 1 or k%total == 0):
return head
count = 1
cur = head
temp = head
while(temp):
if(c == count):
break
temp = temp.next
count += 1
count = 1
ans = temp
while(cur):
if(count < c):
while(temp.next):
temp = temp.next
temp.next = ListNode(cur.val)
temp = temp.next
cur = cur.next
count += 1
return ans
```
#### [238\. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/)
- 題目解釋
將array內的內容改為其餘數字的乘積總和
- 解題思路
注意出現0時的狀況,並且記錄數量,如果大於2代表所有輸出為0,其餘數字僅需避開乘上0的情況
- 程式碼
```python=1
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
total = 1
zeroflag = 0
zerocount = 0
for i in nums:
if(i != 0):
total = total * i
else:
zeroflag = 1
zerocount += 1
if(zerocount >= 2):
return [0] * len(nums)
if(zerocount == len(nums)):
return nums
for i in range(len(nums)):
if(zeroflag == 1 and nums[i] != 0):
nums[i] = 0
elif(zeroflag == 1 and nums[i] == 0):
nums[i] = total
else:
nums[i] = total // nums[i]
return nums
```
#### [1897\. Redistribute Characters to Make All Strings Equal](https://leetcode.com/problems/redistribute-characters-to-make-all-strings-equal/)
- 題目解釋
經由互換字母之後是否可以讓所有word都長一樣
- 解題思路
使用dict紀錄所有字母出現次數,最後除上word長度即可
- 程式碼
```python=1
class Solution:
def makeEqual(self, words: List[str]) -> bool:
a = dict()
for i in words:
for j in range(len(i)):
if(i[j] in a):
a[i[j]] += 1
else:
a[i[j]] = 1
for x,y in a.items():
if y % len(words) != 0:
return False
return True
```
####
- 題目解釋
題目本身解釋不好,加上測試範例容易誤會,實際上是找出每個數字裡的最大數字,例如79最大為9,12最大為2,找出陣列中擁有相同最大數字並相加,最終將相加後最大數字輸出。
- 解題思路
分為兩個func,一個負責使用python套件count,找出最大數字為何,另一個則是去判斷相同者相加且最大數字總和為何。
- 程式碼
```python=1
class Solution:
def findmax(self,target: int) -> int:
num = [9,8,7,6,5,4,3,2,1]
for i in num:
if(str(target).count(str(i))>0):
return i
return 0
def maxSum(self, nums: List[int]) -> int:
ans = -1
temp = 0
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if(self.findmax(nums[i])==self.findmax(nums[j])):
ans = max(ans,nums[i]+nums[j])
return ans
```
#### [2807\. Insert Greatest Common Divisors in Linked List](https://leetcode.com/problems/insert-greatest-common-divisors-in-linked-list/)
- 題目解釋
給定linkedlist從中插入最大公因數
- 解題思路
最大公因數的解法先寫出,之後使用linkedlist的指標移動進行插入。
- 程式碼
```python=1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def gre(self,a,b):
if(a<b):
temp = a
while(temp>1):
if(b%temp==0 and a%temp==0):
return temp
temp -= 1
return temp
elif(a>b):
temp = b
while(temp > 1):
if(a%temp==0 and b%temp ==0):
return temp
temp -= 1
return temp
else:
return a
def insertGreatestCommonDivisors(self, head: Optional[ListNode]) -> Optional[ListNode]:
a = head
if(a == None or a.next == None):
return a
while(a.next and a.next):
t = self.gre(a.val,a.next.val)
temp = a.next
a.next = ListNode(t)
a = a.next
a.next = temp
a = a.next
return head
```
#### [748\. Shortest Completing Word](https://leetcode.com/problems/shortest-completing-word/)
- 題目解釋
找出符合target字母的單字
- 解題思路
使用dict進行解題,中途如果為0,可以使用del進行刪除
- 程式碼
```python=1
class Solution:
def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str:
a = dict()
for i in licensePlate:
if(ord(i.lower())>=ord('a') and ord(i.lower())<=ord('z')):
if(i.lower() in a):
a[i.lower()] += 1
else:
a[i.lower()] = 1
minl = 25
ans = 0
for i in range(len(words)):
b = a.copy()
for j in range(len(words[i])):
if(words[i][j] in b):
b[words[i][j]] -= 1
if(b[words[i][j]] == 0):
del b[words[i][j]]
if(len(b) == 0 and len(words[i])<minl):
ans = words[i]
minl = len(words[i])
return ans
```
#### 2233. Maximum Product After K Increments
- 題目解釋
給定一段list,增加k次,使得陣列所有數字相成為最大
- 解題思路
可看出由小到大把最小數字往上加即可,但等於每次都需要重新排序,因此可以聯想到使用heap進行解題,每一次都把最小的pop,加完再push,最後,因為有可能數字太大,每次乘完都需要mod取餘數。
- 程式碼
```python=1
class Solution:
def maximumProduct(self, nums: List[int], k: int) -> int:
heapq.heapify(nums)
value = 10**9 + 7
for i in range(k):
temp = heapq.heappop(nums)
temp += 1
heapq.heappush(nums,temp)
total = 1
for i in range(len(nums)):
total = (total * nums[i]) % (10**9 + 7)
return total
```
<!-- ####
- 題目解釋
- 解題思路
- 程式碼
```python=1
```
- 遇到問題
- 新學習
- 時間複雜度
- 空間複雜度 -->