*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.

**Follow up:**

- Could you solve the problem in
`O(1)`

extra memory space? - You may not alter the values in the list’s nodes, only nodes itself may be changed.

```
/**
Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
*/
class Solution {
public ListNode reverse(ListNode start, ListNode end){
ListNode prev = null, next;
// prev = null;
//prev.next = start; // prev.next = 4
while(prev != end){ // 4
next = start.next;
start.next = prev;
prev = start;
start = next;
}
return end;
}
public ListNode reverseKGroup(ListNode head, int k) {
ListNode tmp = new ListNode(0);
ListNode curr = head, root;
root = tmp;
int cnt = 1;
//tmp.next = head;
ListNode prev, prev_prev = null;
prev = head;
while(curr != null){
if(cnt % k == 0){
ListNode tmp_next = curr.next;
reverse(prev, curr);
if(prev_prev == null){
tmp.next = curr;
}else{
prev_prev.next = curr;
}
prev.next = tmp_next;
prev_prev = prev;
prev = curr = tmp_next;
}else{
curr = curr.next;
}
```` cnt++; } return tmp.next;`

}
}

Time Complexity: O(N) Space Complexity: O(1)

]]>To me, rejection is not a big deal. I already got at least 50+ rejections and I think there were many variables of rejection such as I may not ready for the technical interview, or the ideal role for the position was not me, or I had a hard to communicate in English. Since any of company letting me know the reason for rejection, I can’t guarantee but at least I can stay myself to keep my ego.

However, the last interview brought me a different takeaway. It actually touched my ego. It was another senior position. Though the interview question was not difficult, after I got a rejection, I have doubts about my SWE experiences as well as the interview preparation. Am I prepare the right direction? What was a time when I use those data structures and algorithms for my development? I was looking back to the source codes that I wrote down previously and I found there were not too much of the line of code with data structures and algorithms.

Normally, I’ve developed the web which is consists of backend and frontend. Here, I usually used an API framework like Play framework with Scala for the backend and I used ReactJS for the frontend for the last six years. For that one, actually, I didn’t have to pay attention to the data structures and algorithms. The only I need to use was just some primitive types, objects and lists. There were already built-in data manipulating functions like sorting and filtering. And I normally used a map or foreach for the iteration. Since DB is mapped by ORM, I didn’t have to write down pure SQL or data mapping logic. My API server is a sort of.. bypassing server from DB to the endpoint.

I was frustrated when I found there was no effort to consider the data structures and algorithms. I was just googling the working example and adjusted to my code. Or, I was just good at finding relative libraries. That’s all. Since I was starting for the startup, my coding ability was tucked due to the pressure of deadlines.

So, **am I REALLY have 5 years of SWE experiences? I don’t think so. **I’m good at system design but I’m not good at coding itself which is a basic of every software engineer. While I was bent on the entire system design, I overlooked a basic. What a stupid..

Afterward, I just go back to the basics. I choose my main language which is Java, and I focus on basics such as advanced data structure and advanced algorithms preparing with my colleagues. After I feel I’m ready for them, I’ll refactor my previous code. For the Urhyme, it will be replaced by Spring Framework. And I’ll modularize some of the services into small services. For the React part, actually, I don’t know how to refactoring but maybe I’ll use TypeScript. At least, I’ll try to write down myself when I face with developing a new feature.

Even though I determined for the next things that I focus on, I still doubt is there any activity of designing good data structures and algorithms when it comes to web development? Since there are many great libraries, maybe web-based SWE easy to overlooks the importance of data structures and algorithms which is actually working a significant role internally. If I can’t use the open-sourced libraries, maybe it will take a lot of time to develop any kind of web service. These days it’s hard to develop without using any open-sourced libraries, however, we need to dedicate ourselves to elaborate our basic skills as an SWE.

]]>**Example 1:**

Input:l1 = [1,2,4], l2 = [1,3,4]Output:[1,1,2,3,4,4]

**Example 2:**

Input:l1 = [], l2 = []Output:[]

**Example 3:**

Input:l1 = [], l2 = [0]Output:[0]

**Constraints:**

- The number of nodes in both lists is in the range
`[0, 50]`

. `-100 <= Node.val <= 100`

- Both
`l1`

and`l2`

are sorted in**non-decreasing**order.

Easy question. Just iterate both lists and connect to the temporary head list. If l1 or l2 is done, keep doing there is no remain node.

```
# 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, l1: ListNode, l2: ListNode) -> ListNode:
combined = ListNode(0)
head = combined
while l1 and l2:
if l1.val < l2.val:
combined.next = l1
l1, combined = l1.next, combined.next
else:
combined.next = l2
l2, combined = l2.next, combined.next
while l1:
combined.next = l1
l1, combined = l1.next, combined.next
while l2:
combined.next = l2
l2, combined = l2.next, combined.next
return head.next
```

Time Complexity: O(N+M)

Space Complexity: O(1) (constant)

Submission

Runtime: 40 ms, faster than 49.99% of Python3 online submissions for Merge Two Sorted Lists.

Memory Usage: 14.4 MB, less than 34.26% of Python3 online submissions for Merge Two Sorted Lists.

`intervals`

where `intervals[i] = [start`_{i}, end_{i}]

, return **Example 1:**

Input:intervals = [[0,30],[5,10],[15,20]]Output:2

**Example 2:**

Input:intervals = [[7,10],[2,4]]Output:1

**Constraints:**

`1 <= intervals.length <= 10`

^{4}`0 <= start`

_{i}< end_{i}<= 10^{6}

It is another problem I spent about 5 hours until midnight and I finally realized I tried to use the wrong approach.

In here, I only tried to find where is the overlapped position. Since it requires only maximum overlapped interval, I may use the longest one to find max overlaps. However, it has too many cases. Maybe the longest one does not overlap other N-1 cases. Maybe there are all same intervals.

My problem was I treated this problem as a “coordination” problem. I mean, I set x = beginning time and y = finishing time and tried to find overlaps of [x,y] pairs and it brought me a lot of cases! I almost gave up but finally, I got the idea of it.

It was simple. Just sort by beginning/ending time and save into another 1D array/list. Let says A[] has sorted beginning time and B[] has sorted ending time. Then we can get the earliest time from 0 to N in A[] and B[]. If it is from A, then we increase # of rooms. Otherwise, decrease. And check the max # of room for every iteration. Here is my final solution:

```
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
if len(intervals) == 0:
return 0
A = [i for [i,j] in sorted(intervals, key=lambda a: a[0])]
B = [j for [i,j] in sorted(intervals, key=lambda a: a[1])]
s = 0
i,j = 0,0
m = 0
while i < len(A) and j < len(B):
if A[i] < B[j]:
s+=1
i+=1
else:
s-=1
j+=1
m = max(m,s)
return m
```

Time/Space Complexity: O(N)

Submission

Runtime: 76 ms, faster than 75.82% of Python3 online submissions for Meeting Rooms II.

Memory Usage: 17.5 MB, less than 68.85% of Python3 online submissions for Meeting Rooms II.

]]>**Example:**

Input:1->2->3->4->5->NULLOutput:5->4->3->2->1->NULL

**Follow up:**

A linked list can be reversed either iteratively or recursively. Could you implement both?

It is another problem I spent about 3 hours though it is in “easy” category. I’ve solved it about 20 times before but every time when I was trying to solve it, I got so much confusions.

I knew it needs three pointers: prev, curr, next. And I also knew their co-relations. However, somehow it did not work correctly and was not easy to debug.

My problem was my approach. I thought that I can write a code directly with a short thoughts. It bring me a lot of bugs. So, I wrote down every use case based on algorithm what I knew so far, and finally I realized what I’ve missed. In here, I actually need “root” as well and curr pointer should be connected with it. So, my final algorithm is:

- while curr is not null
- curr.next = root (a head node in the list)
- prev.next = next
- root = curr
- move curr to next, and assign curr = next

Here is my final solution.

```
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
prev, curr, next = head, head.next, head.next.next
root = head
root.next = prev
while curr:
curr.next = root
prev.next = next
root=curr
curr = next
if not curr:
break
next = next.next
return root
```

Time Complexity: O(N)

Space Complexity: O(1)**Submissions**

Runtime: 40 ms, faster than 39.24% of Python3 online submissions for Reverse Linked List.

Memory Usage: 15.6 MB, less than 50.50% of Python3 online submissions for Reverse Linked List.

`nums`

, find the contiguous subarray (containing at least one number) which has the largest sum and return **Example 1:**

Input:nums = [-2,1,-3,4,-1,2,1,-5,4]Output:6Explanation:[4,-1,2,1] has the largest sum = 6.

**Example 2:**

Input:nums = [1]Output:1

**Example 3:**

Input:nums = [0]Output:0

**Example 4:**

Input:nums = [-1]Output:-1

**Example 5:**

Input:nums = [-100000]Output:-100000

**Constraints:**

`1 <= nums.length <= 3 * 10`

^{4}`-10`

^{5}<= nums[i] <= 10^{5}

Approach

Although it is in the “easy” category, I spent 9 hours solving it! It was too much but I think my original approach was pretty much messy. I definitely thought there is a brute force approach which was a timeout. So, I realized it should be less than O(N*N) time.

I tried to find some pattern within here. First, save all the sum into another array from [0…i] In above example (-3,4,-1,2,1,-5,4), sum array should be (-3, 1,0,2,3,-2,2) then from the first element, I just subtract that element like, subtract -3 to every [1…i] for the 1st iteration. Then subtract 1 to every [2…i] for the 2nd iteration, for the last element. It sounds like O(NlogN), but it is actually O(N*N) to not be better even I can solve this approach.

Here is my 2nd approach. I made the equation like a[0…i-1]+a[i…j]+a[j+1…n] = k (sum of all) and I was trying to have the smallest a[0…i-1] and a[j+1…n] However, I found that I don’t need to consider either a[0…i-1] or a[j+1…n] because in that case, I should keep saving at least three positions and it is redundant. Furthermore, it could not bring me any kind of insight. So, I gave up.

Lastly, I just thought that what is the “continuous” means. In the sense of continuous, I should decide either to include the next element or start from the next element based on some criteria. For example, in the above example, if I choose [-3] then the next step should be either [-3,4] or [4]. To find the criteria, I finally realized that I don’t need to save the previous sum which was my 2nd approach. I need only keep saving the sum_so_far and if I need to restart, then sum_so_far should be reset and keep saving the maximum sum_so_far. Here is my final solution:

```
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if len(nums) == 0:
return 0
if len(nums) == 1:
return nums[0]
sum_so_far = 0
rslt = -10**5
for num in nums:
sum_so_far = max(sum_so_far + num, num)
rslt = max(rslt, sum_so_far)
return rslt
```

Time Complexity: O(N)

Space Complexity: O(1)

**Submission**

Runtime: 64 ms, faster than 79.02% of Python3 online submissions for Maximum Subarray.

Memory Usage: 14.7 MB, less than 94.57% of Python3 online submissions for Maximum Subarray.

`nums`

of `output`

such that `output[i]`

is equal to the product of all the elements of `nums`

except `nums[i]`

.
**Example:**

Input:`[1,2,3,4]`

Output:`[24,12,8,6]`

**Constraint:** It’s guaranteed that the product of the elements of any prefix or suffix of the array (including the whole array) fits in a 32 bit integer.

**Note: **Please solve it **without division** and in O(*n*).

**Follow up:**

Could you solve it with constant space complexity? (The output array **does not** count as extra space for the purpose of space complexity analysis.)

This problem is a bit tricky. We can do it with division but in the note, we shouldn’t do that. So, first we need to find the pattern. Let’s say prod[i] is a product except itself (i) then:

prod[0] = **nums[1] x nums[2] x nums[3]**

prod[1] = * nums[0]* x

prod[2] =

prod[3] =

Here, we can see some patterns that maybe there is two product (in the above example, see italics and bolds) It also similar as trapping rain water problem or buy and sell stock problem because we can solve it by comparing left and right.

In here, we can see prod[i] = nums[0]*nums[1]*…*nums[i-1]*nums[i+1]*…*nums[N] So, we can split into multiple of before/after position of “i”. To sum up:

prod[i] = products_from_left[i-1]*products_from_right[i+1] where products_from_left[i] = nums[0]*nums[1]*…*nums[i] and products_from_right[i] = nums[i]*nums[i+1]*…*nums[N]

So, we can simply calculate products_from_left and products_from_right. Let’s see my first approach:

```
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
products_from_left, products_from_right = [1]*(n+1), [1]*(n+1) #Initialize
for i in range(1,n):
products_from_left[i] = products_from_left[i-1] * nums[i-1]
products_from_right[n-i-1] = products_from_right[n-i] * nums[n-i]
prod = [1]*n
for i in range(n):
prod[i] = products_from_left[i] * products_from_right[i]
return prod
```

I just implemented all of my explanation above. It beats 12.83% of submissions. Bad but doesn’t matter. but soon I realized it can be much slower than a single loop or maybe I’m wasting spaces like products_from_right and products_from_left. Actually, the follow-up tasks solve it with constant space complexity. So, I was thinking maybe we can use the prod array only. Let’s brought previous equations for the prods:

prod[i] = nums[0]*nums[1]*…*nums[i-1]*nums[i+1]*…*nums[N]

Since multiple can be exchanged between left/right equation, we may first multiple first [0]~[i-1] parts and multiple remain [i+1]~[n] part. So, we can first calculate products_from_right saving directly into the prod, then calculate products_from_left from the right and multiple with the prod.

```
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
prod = [1]*(n+1)
for i in range(1,n):
prod[i] = prod[i-1] * nums[i-1]
mul_sofar = 1
for i in range(n,0,-1):
prod[i-1] *= mul_sofar
mul_sofar *= nums[i-1]
return prod[:-1]
```

Time Complexity: O(N)

Space Complexity: O(1)

Submission

Runtime: 248 ms, faster than 51.06% of Python3 online submissions for Product of Array Except Self.

Memory Usage: 21.5 MB, less than 46.53% of Python3 online submissions for Product of Array Except Self.

`prices`

where `prices[i]`

is the price of a given stock on the `i`^{th}

day.
You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.

Return *the maximum profit you can achieve from this transaction*. If you cannot achieve any profit, return `0`

.

**Example 1:**

Input:prices = [7,1,5,3,6,4]Output:5Explanation:Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.

**Example 2:**

Input:prices = [7,6,4,3,1]Output:0Explanation:In this case, no transactions are done and the max profit = 0.

**Constraints:**

`1 <= prices.length <= 10`

^{5}`0 <= prices[i] <= 10`

^{4}

Approach

I just simply thought I can get the minimum so far and find the max profit comparing minimum and max so far. Let says best[i] is the best profit at ‘i’. Then, best[i] = max_from_right[i] – min_from_left[i]. So, like the “Trapping rainwater” problem, I first calculate every min/max values from both left and right.

```
class Solution:
def maxProfit(self, prices: List[int]) -> int:
minvalues, maxvalues = [sys.maxsize], [-1]
n = len(prices)
flag = False
for i in range(1, n+1):
minvalues.append(min(minvalues[i-1], prices[i-1]))
maxvalues.append(max(maxvalues[i-1], prices[n-i]))
maxvalues.reverse()
#print(minvalues, maxvalues)
maxprofit = 0
for i in range(0, n):
#print(maxvalues[i], minvalues[i])
maxprofit = max(maxvalues[i] - minvalues[i], maxprofit)
return maxprofit
```

Actually, it passed all test cases. However, it seems very slow. It just faster than 7% of online submission and I think I can make a better way. Since there is two for loop, I think I can use a single loop. Maybe I don’t need to calculate every max value so far from right since the current prices will be the potential max value while calculating the min value so far. So, in the position of “i,” not a best but best_guessing[i] = prices[i] – min_so_far In that case, whenever we find prices is maxed value, then we can get the max profit. Here is my final submission

```
class Solution:
def maxProfit(self, prices: List[int]) -> int:
min_so_far = sys.maxsize
maxprofit = 0
for price in prices:
if price < min_so_far:
min_so_far = price
else:
maxprofit = max(price - min_so_far, maxprofit)
return maxprofit
```

Time/Space Complexity: O(N)**Submission**

Runtime: 1036 ms, faster than 29.30% of Python3 online submissions for Best Time to Buy and Sell Stock.

Memory Usage: 25.2 MB, less than 5.44% of Python3 online submissions for Best Time to Buy and Sell Stock.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

**Example 1:**

Input:l1 = [2,4,3], l2 = [5,6,4]Output:[7,0,8]Explanation:342 + 465 = 807.

**Example 2:**

Input:l1 = [0], l2 = [0]Output:[0]

**Example 3:**

Input:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]Output:[8,9,9,9,0,0,0,1]

**Constraints:**

- The number of nodes in each linked list is in the range
`[1, 100]`

. `0 <= Node.val <= 9`

- It is guaranteed that the list represents a number that does not have leading zeros.

Approach is simple. Just looking all of the list pair of list1 and list2, and calculate sum = (list1.val + list2.val + prev_carry)%10 and carry = (list1.val + list2.val + prev_carry) // 10. Loop both list first, and list1, list2 consequentially. If carry is 1 at the last, we should add it to the last element.

```
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
root = ListNode(0)
head = root
s,c = 0,0
while l1 and l2:
s,c = (l1.val+l2.val+c)%10, (l1.val+l2.val+c)//10
root.next = ListNode(s)
l1,l2,root = l1.next, l2.next, root.next
while l1:
s,c = (l1.val+c)%10, (l1.val+c)//10
root.next = ListNode(s)
l1, root = l1.next, root.next
while l2:
s,c = (l2.val+c)%10, (l2.val+c)//10
root.next = ListNode(s)
l2, root = l2.next, root.next
if c != 0:
root.next = ListNode(c)
return head.next
```

Time/Space Complexity: O(N)**Submission**

Runtime: 88 ms, faster than 10.65% of Python3 online submissions for Add Two Numbers.

Memory Usage: 14.4 MB, less than 12.54% of Python3 online submissions for Add Two Numbers.

`intervals`

where `intervals[i] = [start`_{i}, end_{i}]

, merge all overlapping intervals, and return **Example 1:**

Input:intervals = [[1,3],[2,6],[8,10],[15,18]]Output:[[1,6],[8,10],[15,18]]Explanation:Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].

**Example 2:**

Input:intervals = [[1,4],[4,5]]Output:[[1,5]]Explanation:Intervals [1,4] and [4,5] are considered overlapping.

**Constraints:**

`1 <= intervals.length <= 10`

^{4}`intervals[i].length == 2`

`0 <= start`

_{i}<= end_{i}<= 10^{4}

Approach

Sort by 1st element, then check if the next interval is overlapped. If the checking interval’s 1st element is more than the current end time, then change the checking interval to the current interval.

```
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
rslt = []
if len(intervals) == 0:
return rslt
intervals.sort()
start_x, start_y = intervals[0]
for i in range(1, len(intervals)):
if start_y < intervals[i][0]:
rslt.append([start_x, start_y])
start_x, start_y = intervals[i]
elif start_y < intervals[i][1]:
start_y = intervals[i][1]
rslt.append([start_x, start_y])
return rslt
```

Time Complexity: O(NlogN)

Space Complexity: O(1)

Optimization: maybe we can use the heap?

**Submission**

Runtime: 92 ms, faster than 35.73% of Python3 online submissions for Merge Intervals.

Memory Usage: 16.3 MB, less than 12.13% of Python3 online submissions for Merge Intervals.