# LandIsland-LeetCode+English Project
## [Recursion]2021.12.05 21:00 Host: David
### [347. Top K Frequent Elements](https://leetcode.com/problems/powx-n/)(David)
SOL 1:
```js=
var myPow = function(x, n) {
if (n == 0){
return 1;
}
if (n == 1){
return x;
}
if (n == -1) {
return 1/x;
}
if(n%2 == 0){
return myPow(x*x, n/2) ;
}else{
return x * myPow(x*x, (n-1)/2) ;
}
};
```
## [HashMap]2021.11.21 21:00 Host: JinWei
### [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements)(Jinwei)
SOL 1: JW
```js=
function topKFrequent(nums, k) {
let map = new Map();
nums.forEach((eachNum) => {
if (map.get(eachNum)) {
const numAmount = map.get(eachNum);
map.set(eachNum, numAmount + 1);
} else {
map.set(eachNum, 1);
}
});
// sort
const sortMap = new Map([...map.entries()].sort((a, b) => b[1] - a[1]));
const finalArr = [];
sortMap.forEach((val, key) => {
let idx = 0;
if (idx < k) {
finalArr.push(key);
idx++;
}
});
return finalArr;
}
```
SOL2 : Online
```js=
var topKFrequent = function(nums, k) {
const count = new Map()
const bucket = Array.from({ length: nums.length + 1 }, _ => [])
for (const n of nums) {
count.set(n, (count.get(n) || 0) + 1)
}
for (const entry of count.entries()) {
const [n, freq] = entry
bucket[freq].push(n)
}
return bucket.flat().slice(-k)
};
```
### [1282. Group the People Given the Group Size They Belong To](https://leetcode.com/problems/group-the-people-given-the-group-size-they-belong-to/)(Even Pan)
#### solution 1 (Even)
```python=
class Solution:
def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]:
self.room = {} # key: seat, value: List[list]
for idx, menber_group in enumerate(groupSizes):
self.check_room_seat(menber_group, idx)
result = []
for i in self.room.values():
result.extend(i)
return result
def check_room_seat(self, seat, idx):
self.room.setdefault(seat, [[]])
if len(self.room.get(seat)[-1]) < seat:
self.room[seat][-1].append(idx)
else:
self.create_new_room(seat, idx)
def create_new_room(self, seat, idx):
self.room[seat].append([idx])
```
#### solution 2 source:[ online](https://leetcode.com/problems/group-the-people-given-the-group-size-they-belong-to/discuss/448447/Python-Simple.-Hashmap.-With-comments-(beats-99))
```python=
class Solution:
def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]:
'''
Example input-> groupSizes=[3,3,3,3,3,1,3]
Store in a dictionary[i] the list of indices of input array groupSizes that belong to a group size i
'''
_dict_=collections.defaultdict(list)
for idx,i in enumerate(groupSizes):
_dict_[i].append(idx)
'''
print (_dict_)-> defaultdict(<class 'list'>, {3: [0, 1, 2, 3, 4, 6], 1: [5]})
_dict_[i] has list of indices of input array groupSizes that belong to groupsize i
Next, create lists of size i parsing through _dict_[i], and append them to answer[].
Further since a solution is guaranteed to exist, len(_dict_[i])/i will always be perfectly divisible.
Infact, len(_dict_[i])/i gives exactly the number of groups of size i
'''
answer=[]
for key, lst in _dict_.items():
for idx in range(0, len(lst), key):
answer.append(lst[idx:idx + key])
return (answer)
```
## [Array]2021.11.14 21:00 Host: Rosy
### [807. Max Increase to Keep City Skyline](https://leetcode.com/problems/max-increase-to-keep-city-skyline/)(Even Pan)
```python=
# slow solution
# time = O(n^2)
# space = O(n)
class Solution:
def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int:
grid_copy = [[0]*len(grid) for _ in range(len(grid[0]))]
additional_level = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
max_x = max(grid[i])
max_y = max([i[j] for i in grid])
# print('x: ', max_x, ';y: ', max_y)
grid_copy[i][j] = min(max_x, max_y)
additional_level += grid_copy[i][j] - grid[i][j]
print(grid_copy)
print(grid)
return additional_level
# fast solution
# time = O(n)
# space = O(log(n))
class Solution:
def maxIncreaseKeepingSkyline(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
ops = 0
max1=[]
max2=[]
# print(zip(*grid))
# print([i for i in zip(*grid)])
for i in grid:
max1.append(max(i))
print(max1)
for j in list(zip(*grid)):
max2.append(max(j))
print(max2)
for i1, val1 in enumerate(max1):
for i2, val2 in enumerate(max2):
ops+=(min(val1, val2)-grid[i1][i2])
return ops
```
## [Hash Table]2021.11.7 21:00 Host: Iris
### [480. Sliding Window Median](https://leetcode.com/problems/sliding-window-median/)(Even Pan)
```python=
class Solution:
def median(self, nums):
""" calculate median in a list of sorted numbers
Argument:
nums: list, list of numbers which is sorted
Return:
return median number if it list have odd length
else return average of two median numbers
"""
mid = len(nums) // 2
if len(nums) % 2:
return nums[mid]
return (nums[mid-1] + nums[mid]) / 2
def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
if not nums:
return []
window = sorted(nums[:k-1])
result = []
for idx, n in enumerate(nums[(k-1):]):
self.insert_new_num(window,n)
result.append(self.median(window))
self.remove_old_num(window, nums[idx])
return result
@staticmethod
def find_insert_loc(li , num):
""" find the index for num in a sorted list
Argument:
li: list, sorted list to be insert
num: int, num to be insert
Return:
lo: int, index for insert in the list
Example:
case1: [1,2,3,4], 2 -> ([1,2,(2),3,3]) ... 2
case2: [1,4,5,7,10], 8 -> ([1,4,5,7,8,10]) ... 4
case3: [1,4,5,7,10], 6 -> ([1,4,5,6,7,10]) ... 3
psudo
mid = 2, << lo= 2+1
mid = (3+5) =4 num[min] = 10 >> hi = 4
mid = 3 num[3] = 7 >> hi = 3 , hi == lo break
case 3 output example:
mid: 2 , li[mid]: 5
0 5 2 5
update lo 0 to 3
mid: 4 , li[mid]: 10
3 5 4 10
update hi 5 to 4
mid: 3 , li[mid]: 7
3 4 3 7
update hi 4 to 3
3
"""
hi = len(li)
lo = 0
while lo < hi:
mid = (lo + hi) // 2
# print('mid: ', mid, ', li[mid]: ', li[mid])
if num < li[mid]:
# print(lo, hi, mid, li[mid])
# print(f'update hi {hi} to {mid}')
hi = mid
else:
# print(lo, hi, mid, li[mid])
# print(f'update lo {lo} to {mid + 1}')
lo = mid + 1
return lo
def insert_new_num(self, li, num):
""" insert num in the sorted list
Arguments:
li: list, input sorted list
num: int, input number
Example:
case1: ([1,2,3,4], 2) -> [1,2,(2),3,3]
case2: ([1,4,5,7,10], 8) -> [1,4,5,7,(8),10]
case3: ([1,4,5,7,10], 6) -> [1,4,5,(6),7,10]
"""
loc = self.find_insert_loc(li, num)
li.insert(loc, num)
def remove_old_num(self, li, num):
""" remove num in sorted list
Arguments:
li: list, input sorted list
num: int, number to be remove
Example:
case1: ([1,2,2,3,3], 2) -> [1,2,3,3]
case2: ([1,4,5,7,8,10], 8) -> [1,4,5,7,10]
case3: ([1,4,5,6,7,10], 6) -> [1,4,5,7,10]
"""
loc = self.find_insert_loc(li, num) - 1
del li[loc]
```
### [1817. Finding the Users Active Minutes](https://leetcode.com/problems/finding-the-users-active-minutes/) (Iris)
- Solution1
```javascript=
var findingUsersActiveMinutes = function(logs, k) {
const m = new Map();
const result = new Array(k).fill(0)
logs.forEach((arr)=>{
const id = arr[0];
const minute = arr[1];
if(!m.has(id)){
m.set(id,[minute])
}else{
const prev = m.get(id);
if(!prev.includes(minute)){
// arr.includes time complexity = O(n)
prev.push(minute);
m.set(id,prev);
}
}
})
for(let i of m){
const len = i[1].length;
result[len-1]++;
}
return result;
};
//Space Complexity = O(n + k)
```
- Solution2
use set and conditional operator to polish
```javascript=
var findingUsersActiveMinutes = function(logs, k) {
const map = new Map();
logs.forEach(([id, time]) => {
const set = map.has(id) ? map.get(id) : new Set();
set.add(time);
map.set(id, set);
})
const result = new Array(k).fill(0);
map.forEach((value, key) => {
if(value.size <= k) {
result[value.size - 1] ++;
}
})
return result;
};
```
## [Dynamic Prog.]2021.10.31 9:00 Host: Aaron
### [96. Unique Binary Search Tree](https://leetcode.com/problems/unique-binary-search-trees/submissions/)
G(n) the number of unique BST for a sequence of length n
F(i,n): the number of unique BST, where the number i is the root of BST, and the sequence ranges from 1 to n.
G(n)= F(1,n)+F(2,n)+.....F(n,n)
G(3)= F(1,3)+F(2,3)+F(3,3)
G(0)=1, G(1)=1
F(3,7)=G(2)*G(4) [1,2] [4,5,6,7]
F(i,n)=G(i-1)*G(n-i) 1 <= i <= n
G(n)=G(0)*G(n-1)+G(1)*G(n-2)....G(n-1)*G(0)
- Solution 1
Explaination:https://leetcode.com/problems/unique-binary-search-trees/discuss/31666/DP-Solution-in-6-lines-with-explanation.-F(i-n)-G(i-1)-*-G(n-i)
```python=
class Solution(object):
def numTrees(self, n):
"""
:type n: int
:rtype: int
"""
g={}
for i in range(n+1):
g[i]=0
g[0]=1
g[1]=1
for i in range(2,(n+1)):
for j in range(1,(i+1)):
g[i]+=g[j-1]*g[i-j]
return g[n]
```
range(1,5) 1 2 3 4
---
### [877. Stone Game](https://leetcode.com/problems/stone-game/) (Tim)
- Solution 1
```cpp=
class Solution{
public:
bool stoneGame(vector<int>& piles){
int n = piles.size();
// dparray[i][j] represents # of stones which Alice has
// more than Bob when playing game from piles i to j.
int dparray[n][n];
// initialize dparray with zero
memset(dparray, 0, sizeof(dparray));
// initialize last step (only 1 pile left)
for(int i=0; i<n; i++) dparray[i][i] = -piles[i];
// fill out the dparray
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
if((i+j)%2==0){
// Alice's turn, try to maximise final result
dparray[i][j] = max(piles[i]+dparray[i+1][j],
piles[j]+dparray[i][j-1]);
} else{
// Bob's turn, try to minimise final result
dparray[i][j] = min(piles[i]+dparray[i+1][j],
piles[j]+dparray[i][j-1]);
}
}
}
return dparray[0][n-1];
}
}
```
- Solution 2
```cpp=
class Solution{
public:
bool stoneGame(vector<int>& piles){
// since the first one to play the game can always
// take all the odd or even piles, he/she can easily
// sum up and choose the subset with more stones
// and win.
return true;
}
}
```
---
### [581. Coin Change 2](https://leetcode.com/problems/coin-change-2/) (Jinwei)
---
### [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) (Rosy)
---
### [119. Pascal's Triangle II](https://leetcode.com/problems/pascals-triangle-ii/) (Jing)
---
### [22. Generate Parentheses](https://leetcode.com/problems/generate-parentheses/) (Aaron)
---
### [338. Counting Bits](https://leetcode.com/problems/counting-bits/) (Iris)
---
## [Array]2021.10.24 12:00 Host:Iris
### [78. Subsets](https://leetcode.com/problems/subsets/solution/)(Iris)
- Solution 1 (cascading)
```javascript=
var subsets = function(nums) {
let output = [[]]
for (num of nums) {
output.forEach((el)=>{
const newArr = [...el, num]
output.push(el)
}
)
}
return output
};
```
- Solution 2 (Backtracking)recursion
```javascript=
const subsets = function(nums) {
const output = [];
function backtrack(start, list){
if(start > nums.length) return;
output.push([...list])
for(let idx = start; idx < nums.length; idx++){
list.push(nums[idx])
backtrack(idx+1, list)
list.pop()
}
}
backtrack(0,[])
return output
};
```
## [Array]2021.10.24 21:00 Host:Even
### [68. Text Justification](https://leetcode.com/problems/text-justification/)(Even)
```py
from typing import List
class Solution:
def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
print(self.better_spacer(room=3, count_words=3))
self.maxWidth = maxWidth
result = []
new_line = []
current_loading = 0
all_length = len(words)
for i, word in enumerate(words):
word_length = len(word)
if current_loading + word_length > maxWidth:
print('need next line')
result.append(new_line.copy())
new_line = []
current_loading = 0
new_line.append(word)
current_loading += word_length + 1
print('newline = ', new_line, 'current loading: ',current_loading)
if i == all_length - 1:
result.append(new_line.copy())
result = self.format_result(result)
return result
def format_result(self, result: List[List[str]]) -> List[str]:
last_line = result[-1]
standard_lines = result[:-1]
formated_lines = []
for line in standard_lines:
formated_lines.append(self.justify_space(line))
formated_lines.append(self.justify_space(last_line, True))
return formated_lines
def justify_space(self, line: list, is_last: bool=False) -> str:
count_words = len(line)
room = self.maxWidth - sum(len(word) for word in line)
if is_last:
formated_line = " ".join(line) + " " * (room - (count_words - 1))
else:
# # use self.better_spacer
space_list = self.better_spacer(room, count_words)
formated_line = self.format_spaces(space_list, line, count_words)
# old method 如果空格不能整除,會失效,引入better spacer 跟 format space解決
# spaces = round(room/(count_words - 1))
# formated_line = (" "*spaces).join(line)
return formated_line
@staticmethod
def better_spacer(room, count_words) -> list:
# 最後一格只有餘數個空格
# aaabb floor(room/count_words) = b , n個a , room%count_words
if count_words == 1:
return [room]
space_list = [floor(room/(count_words - 1))] * (count_words - 1)
for i in range(room%(count_words - 1)):
space_list[i] += 1
return space_list
@staticmethod
def format_spaces(space_list, line, count_words):
formated_line = line[0]
for i in range(len(space_list)):
formated_line += " " * space_list[i]
try:
formated_line += line[i+1]
except Exception:
pass
return formated_line
```
## [Linked list]2021.10.17 21:00 Host: David
### [142. Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) (David)
- Solution 1
```javascript=
var detectCycle = function(head) {
let node_pointers = []
let node = head
while(1){
if(node_pointers.indexOf(node) !== -1){
return node
}
if(node == null){
return null
}
node_pointers.push(node)
node = node.next
}
}
```
- Solution 2
(https://medium.com/@ChYuan/leetcode-no-142-linked-list-cycle-ii-%E5%BF%83%E5%BE%97-medium-c5b53dcca804)
```javascript=
var detectCycle = function(head) {
let dummy = new ListNode();
dummy.next = head;
let node_slow = dummy;
let node_fast = dummy;
while(1){
if( node_fast == null){
return null
}
if( node_fast.next == null){
return null
}
node_slow = node_slow.next;
node_fast = node_fast.next.next;
if (node_slow == node_fast){
node_slow = dummy;
while(1){
node_slow = node_slow.next
node_fast = node_fast.next
if(node_slow == node_fast){
return node_slow
}
}
}
}
};
```
Comment
Jinwei: Super Brilliant! 👍
---
### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) (Jinwei)
<a href="shorturl.at/givLV">
Visualization Process</a>
```javascript=
var deleteDuplicates = function(head) {
let cur = head;
while (cur && cur.next) {
let nextNextNode = cur.next.next;
if (cur.val === cur.next.val) {
cur.next.next = null;
cur.next = nextNextNode;
} else {
cur = cur.next;
}
}
return head;
};
```
---
### [234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) (Aaron)
- Solution 1
```javascript=
var isPalindrome = function(head) {
var sequence = "";
var reverse = "";
while(head != null){
sequence += head.val;
reverse = head.val + reverse;
head = head.next;
}
return sequence == reverse;
};
// space complexity: O(n)
// time complexity: O(n)
```
- Solution 2
```javascript=
var isPalindrome = function(head) {
var middle = findMiddle(head);
var rNode = reverseNode(middle);
while(rNode != null){
if(head.val != rNode.val) {
return false;
}
head = head.next;
rNode = rNode.next;
}
return true;
function findMiddle(node){
var fast = node;
var slow = node;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
function reverseNode(node){
if(node==null || node.next==null) return node;
var prev = null;
var cur = node;
while(cur != null){
var temp = cur;
cur = cur.next;
temp.next = prev;
prev = temp;
}
return prev;
}
};
// space complexity: O(1)
// time complexity: O(n)
```
---
## [Array]2021.10.10 21:00 Host: Iris
### [134. Gas Station](https://leetcode.com/problems/gas-station/) (Iris)
- Solution1
```javascript=
var canCompleteCircuit = function(gas, cost) {
let start = 0, tank = 0, total = 0;
// best option = a gas station that allows us to arrive the next station
// find a optimal strat point
for(let i = 0; i < gas.length; i++) {
const consume = gas[i] - cost[i];
tank += consume;
if(tank < 0) {
tank = 0;
start = i + 1;
}
// tank > 0 = find a start station => start will stay in that index
// to calculate if we can complete the curcuit
total += consume;
}
return total < 0 ? -1 : start;
};
```
- Solution2
```
var canCompleteCircuit = function(gas, cost) {
.....
};
```