only 2 lines. ]]>

class Solution:

def reverse(self, x):

"""

:type x: int

:rtype: int

"""

isNegative = False

if(x<0):

isNegative = True

x = abs(x)

s = ''.join(reversed(str(x)))

s = int(s)

if(isNegative):

s = -s

if(abs(s) > 2**31):

s = 0

return s

''' ]]>

`I -- A naive idea towards the solution`

To begin with, you may be surprised by the basic ideas to approach the problem: simply simulate each of the round trips and choose the one that yields the maximum number of cherries.

But then what's the difficulty of this problem? The biggest issue is that there are simply too many round trips to explore -- the number of round trips scales exponentially as the size `N`

of the `grid`

. This is because each round trip takes `(4N-4)`

steps, and at each step, we have two options as to where to go next (in the worst case). This puts the total number of possible round trips at `2^(4N-4)`

. Therefore a naive implementation of the aforementioned idea would be very inefficient.

`II -- Initial attempt of DP`

Fortunately, a quick look at the problem seems to reveal the two features of dynamic programming: optimal substructure and overlapping of subproblems.

Optimal substructure: if we start from some position `(i, j)`

(assume it's not a thorn) of the `grid`

and want to pick up maximum number of cherries along the path `(i, j) ==> (N-1, N-1) ==>(0, 0)`

, we could move one step forward to either `(i+1, j)`

or `(i, j+1)`

, and recursively solve for the subproblems starting from each of those two positions, then take the sum of the larger one (assume it exists) together with `grid[i][j]`

to form a solution to the original problem. (**Note**: the previous analyses assume we are on the first leg of the round trip, that is, `(0, 0) ==> (N-1, N-1)`

; if we are on the second leg, that is, `(N-1, N-1) ==> (0, 0)`

, then we should move one step backward from `(i, j)`

to either `(i-1, j)`

or `(i, j-1)`

.)

Overlapping of subproblems: two round trips may overlap with each other in the middle, leading to repeated subproblems. For example, the position `(i, j)`

could be reached from both positions `(i-1, j)`

and `(i, j-1)`

. Therefore we may cache the intermediate results to avoid recomputing these subproblems.

This sounds promising, since there are at most `O(N^2)`

starting positions, meaning we could solve the problem in `O(N^2)`

time with caching. But there is an issue with this naive DP -- it failed to take into account the constraint that "**once a cherry is picked up, the original cell (value 1) becomes an empty cell (value 0)**", so that if there are overlapping cells between the two legs of the round trip, those cells will be counted twice. In fact, without this constraint, we can simply solve for the maximum number of cherries of the two legs of the round trip separately (they should have the same value), then take the sum of the two to produce the answer.

`III -- Second attempt of DP that modifies the grid matrix`

So how do we account for the aforementioned constraint? I would say, why don't we reset the value of the cell from `1`

to `0`

after we pick up the cherry? That is, modify the `grid`

matrix as we go along the round trip.

**1. Can we still divide the round trip into two legs and maximize each of them separately ?**

Well, you may be tempted to do so as it seems to be right at first sight. However, if you dig deeper, you will notice that the maximum number of cherries of the second leg actually depends on the choice of path for the first leg. This is because if we pluck some cherry in the first leg, it will no longer be available for the second leg (remember we reset the cell value from `1`

to `0`

). So the above greedy idea only maximize the number of cherries for the first leg, but not necessarily for the sum of the two legs (that is, local optimum does not necessarily lead to global optimum).

Here is a counter example:

```
grid = [[1,1,1,0,1],
[0,0,0,0,0],
[0,0,0,0,0],
[0,0,0,0,0],
[1,0,1,1,1]].
```

The greedy idea above would suggest a `Z`

-shaped path for the first leg, i.e., `(0, 0) ==> (0, 2) ==> (4, 2) ==> (4, 4)`

, which garners `6`

cherries. Then for the second leg, the maximum number of cherries we can get is `1`

(the one at the lower-left or upper-right corner), so the sum will be `7`

. This is apparently less than the best route by traveling along the four edges, in which all `8`

cherries can be picked.

**2. What changes do we need to make on top of the above naive DP if we are modifying the grid matrix ?**

The obvious difference is that now the maximum number of cherries of the trip not only depends on the starting position `(i, j)`

, but also on the **status** of the `grid`

matrix when that position is reached. This is because the `grid`

matrix may be modified differently along different paths towards the same position `(i, j)`

, therefore, even if the starting position is the same, the maximum number of cherries may be different since we are working with different `grid`

matrix now.

Here is a simple example to illustrate this. Assume we have this `grid`

matrix:

```
grid = [[0,1,0],
[0,1,0],
[0,0,0].
```

and we are currently at position `(1, 1)`

. If this position is reached following the path `(0, 0) ==> (0, 1) ==> (1, 1)`

, the `grid`

matrix will be:

```
grid = [[0,0,0],
[0,1,0],
[0,0,0].
```

However, if it is reached following the path `(0, 0) ==> (1, 0) ==> (1, 1)`

, the `grid`

matrix will be the same as the initial one:

```
grid = [[0,1,0],
[0,1,0],
[0,0,0].
```

Therefore starting from the same initial position `(1, 1)`

, the maximum number of cherries will be `1`

for the former and `2`

for the latter.

So now each of our subproblems can be denoted symbolically as `T(i, j, grid.status)`

, where the status of the `grid`

matrix may be represented by a string with cell values joined row by row. Our original problem will be `T(0, 0, grid.initial_status)`

and the recurrence relations are something like:

`T(i, j, grid.status) = -1`

, if `grid[i][j] == -1 || T(i + d, j, grid.status1) == -1 && T(i + d, j, grid.status2) == -1`

;

`T(i, j, grid.status) = grid[i][j] + max(T(i + d, j, grid.status1), T(i, j + d, grid.status2))`

, otherwise.

Here `d`

depends on which leg we are during the round trip (`d = +1`

for the first leg and `d = -1`

for the second leg), both `grid.status1`

and `grid.status2`

can be obtained from `grid.status`

.

To cache the intermediate results, we may create an `N-by-N`

matrix of HashMaps, where the one at position `(i, j)`

will map each `grid.status`

to the maximum number of cherries obtained starting from position `(i, j)`

on the grid with that particular status.

**3. What is the issue with this new version of DP ?**

While we can certainly develop a solution using this new version of DP, it does **NOT** help reduce the time complexity substantially. While it does help improve the performance, the worst case time complexity is still exponential. The reason is that the number of `grid.status`

is very large -- in fact, it is exponential too, as each path may lead to a unique `grid.status`

and the number of paths to some position is exponential. So the possibility of overlapping subproblems becomes so slim that we are forced to compute most of the subproblems, leading to the exponential time complexity.

`IV -- Final attempt of DP without modifying the grid matrix`

So we have seen that modifying the `grid`

matrix is not really the way to go. But if we leave it intact, how do we account for the aforementioned constraint?

The key here is to avoid duplicate counting. But for now, let's forget about the constraint and define `T(i, j)`

as the maximum number of cherries for the round trip `(0, 0) ==> (i, j) ==> (0, 0)`

without modifying the `grid`

matrix. We will see what we can do to avoid the duplicate counting. The original problem will be denoted as `T(N-1, N-1)`

. To obtain the recurrence relations, note that we have two options for arriving at position `(i, j)`

and two options for leaving it: `(i-1, j)`

and `(i, j-1)`

. So the above round trip can be divide into four cases:

Case 1: `(0, 0) ==> (i-1, j) ==> (i, j) ==> (i-1, j) ==> (0, 0)`

Case 2: `(0, 0) ==> (i, j-1) ==> (i, j) ==> (i, j-1) ==> (0, 0)`

Case 3: `(0, 0) ==> (i-1, j) ==> (i, j) ==> (i, j-1) ==> (0, 0)`

Case 4: `(0, 0) ==> (i, j-1) ==> (i, j) ==> (i-1, j) ==> (0, 0)`

By definition, Case 1 is equivalent to `T(i-1, j) + grid[i][j]`

and Case 2 is equivalent to `T(i, j-1) + grid[i][j]`

. However, our definition of `T(i, j)`

does not cover the last two cases, where the end of the first leg and the start of the second leg are different. This suggests we should generalize our definition from `T(i, j)`

to `T(i, j, p, q)`

, which denotes the maximum number of cherries for the two-leg trip `(0, 0) ==> (i, j); (p, q) ==> (0, 0)`

without modifying the `grid`

matrix. Similarly to the analyses above, there are two options for arriving at `(i, j)`

, and two options for leaving `(p, q)`

, so the two-leg trip again can be divided into four cases:

Case 1: `(0, 0) ==> (i-1, j) ==> (i, j); (p, q) ==> (p-1, q) ==> (0, 0)`

Case 2: `(0, 0) ==> (i-1, j) ==> (i, j); (p, q) ==> (p, q-1) ==> (0, 0)`

Case 3: `(0, 0) ==> (i, j-1) ==> (i, j); (p, q) ==> (p-1, q) ==> (0, 0)`

Case 4: `(0, 0) ==> (i, j-1) ==> (i, j); (p, q) ==> (p, q-1) ==> (0, 0)`

then by definition, we have:

Case 1 is equivalent to `T(i-1, j, p-1, q) + grid[i][j] + grid[p][q]`

;

Case 2 is equivalent to `T(i-1, j, p, q-1) + grid[i][j] + grid[p][q]`

;

Case 3 is equivalent to `T(i, j-1, p-1, q) + grid[i][j] + grid[p][q]`

;

Case 4 is equivalent to `T(i, j-1, p, q-1) + grid[i][j] + grid[p][q]`

;

Therefore, the recurrence relations can be written as:

`T(i, j, p, q) = grid[i][j] + grid[p][q] + max{T(i-1, j, p-1, q), T(i-1, j, p, q-1), T(i, j-1, p-1, q), T(i, j-1, p, q-1)}`

Since we already counted `grid[i][j]`

and `grid[p][q]`

towards `T(i, j, p, q)`

, to avoid duplicate counting, both of them should **NOT** be counted for any of `T(i-1, j, p-1, q)`

, `T(i-1, j, p, q-1)`

, `T(i, j-1, p-1, q)`

or `T(i, j-1, p, q-1)`

. This implies the position `(i, j)`

should be lying outside the rectangle `[0, 0, p, q]`

, and similarly the position `(p, q)`

should be lying outside the rectangle `[0, 0, i, j]`

(a special case can happen when the two positions overlap with each other, i.e., `i == p && j == q`

). Mathematically, to avoid duplicate counting, one of the following three conditions should be true:

`i < p && j > q`

`i == p && j == q`

`i > p && j < q`

Of course, we may redefine our `T(i, j, p, q)`

to incorporate these conditions, so that it denotes the maximum number of cherries for the two-leg trip `(0, 0) ==> (i, j); (p, q) ==> (0, 0)`

without modifying the `grid`

matrix and without violating the aforementioned constraint. But this would break its self-consistency so that the above recurrence relation won't work anymore. For example, `T(3, 1, 2, 3)`

is valid under the condition but one of the terms in the recurrence relations `T(2, 1, 2, 2)`

would be invalid.

To retain the self-consistency of `T(i, j, p, q)`

, meanwhile incorporate the above conditions, we can impose a subset of the conditions. This comes from the observation that when `i`

(`p`

) increases, we need to decrease `j`

(`q`

) in order to make the above conditions hold, and vice versa. So it seems that we can set the sum of `i`

(`p`

) and `j`

(`q`

) to a constant, `n = i + j = p + q`

. Then the above conditions will be met automatically.

So now we need to redefine our `T(i, j, p, q)`

under the condition such that `n = i + j = p + q`

, and we rename it as `T(n, i, p)`

, where `T(n, i, p) = T(i, n-i, p, n-p)`

. note that under this definition, we have:

`T(i-1, n-i, p-1, n-p) = T(n-1, i-1, p-1)`

`T(i-1, n-i, p, n-p-1) = T(n-1, i-1, p)`

`T(i, n-i-1, p-1, n-p) = T(n-1, i, p-1)`

`T(i, n-i-1, p, n-p-1) = T(n-1, i, p)`

Then from the recurrence relation for `T(i, j, p, q)`

, we obtain the recurrence relation for `T(n, i, p)`

as:

`T(n, i, p) = grid[i][j] + grid[p][q] + max{T(n-1, i-1, p-1), T(n-1, i-1, p), T(n-1, i, p-1), T(n-1, i, p)}`

.

Of course, in the recurrence relation above, only one of `grid[i][j]`

and `grid[p][q]`

will be taken if `i == p`

, that is, when the two positions overlap. Note that all four indices, `i`

, `j`

, `p`

and `q`

will be in the range `[0, N)`

, while `n`

is in the range `[0, 2N-1)`

(remember it is the sum of `i`

and `j`

).

Now using the recurrence relation for `T(n, i, p)`

, it is straightforward to code for the `O(N^3)`

time and `O(N^3)`

space solution. However, if you notice that `T(n, i, p)`

only depends on those subproblems with `n - 1`

, we can iterate on this dimension and cut down the space to `O(N^2)`

. So here is the final `O(N^3)`

time and `O(N^2)`

space solution:

```
public int cherryPickup(int[][] grid) {
int N = grid.length, M = (N << 1) - 1;
int[][] dp = new int[N][N];
dp[0][0] = grid[0][0];
for (int n = 1; n < M; n++) {
for (int i = N - 1; i >= 0; i--) {
for (int p = N - 1; p >= 0; p--) {
int j = n - i, q = n - p;
if (j < 0 || j >= N || q < 0 || q >= N || grid[i][j] < 0 || grid[p][q] < 0) {
dp[i][p] = -1;
continue;
}
if (i > 0) dp[i][p] = Math.max(dp[i][p], dp[i - 1][p]);
if (p > 0) dp[i][p] = Math.max(dp[i][p], dp[i][p - 1]);
if (i > 0 && p > 0) dp[i][p] = Math.max(dp[i][p], dp[i - 1][p - 1]);
if (dp[i][p] >= 0) dp[i][p] += grid[i][j] + (i != p ? grid[p][q] : 0)
}
}
}
return Math.max(dp[N - 1][N - 1], 0);
}
```

]]>```
public int GetSum(int a, int b)
{
int[] numbers = new int[2] { a, b };
return (int)numbers.Sum();
}
```

]]>```
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> graph(numCourses);
vector<int> depth(numCourses, 0);
for(auto m: prerequisites){
graph[m.second].push_back(m.first);
depth[m.first]++;
}
queue<int> q;
for(int i = 0; i < numCourses; i++){
if(depth[i] == 0)
q.push(i);
}
int count = 0;
while(!q.empty()){
int course_num = q.front();
q.pop();
count++;
for(int i = 0; i < graph[course_num].size(); i++){
if(--depth[graph[course_num][i]] == 0)
q.push(graph[course_num][i]);
}
}
return count == numCourses;
}
```

]]>public static int distance(int a, int b) {

return Integer.bitCount(a ^ b);

}

```
class Solution {
public:
vector<ListNode *> splitListToParts(ListNode *root, int k) {
vector<ListNode *> ret(k, NULL), tmp;
ListNode *last_node = NULL;
int count = 0;
while (root) {
ListNode *lnode = new ListNode(root->val);
lnode->next = root->next;
tmp.push_back(lnode);
if (last_node) {
last_node->next = lnode;
}
count++;
last_node = lnode;
root = root->next;
}
int k_div = count / k, k_mod = count % k, last = 0;
for (int i = 0; i < k && i < count; ++i) {
ret[i] = tmp[last];
if (i < k_mod) {
last += (k_div + 1);
} else {
last += k_div;
}
tmp[last - 1]->next = NULL;
}
return ret;
}
};
```

]]>```
class MyCalendarTwo {
List<int[]> list;
public MyCalendarTwo() {
list = new ArrayList<>();
}
public boolean book(int start, int end) {
int count = 0;
List<int[]> toAdd = new ArrayList<>();
for (int[] arr : list) {
if (arr[1] <= start || arr[0] >= end) {
continue;
}
int[] overlap = new int[]{Math.max(start, arr[0]), Math.min(end, arr[1])};
count++;
if (count >= 3) return false;
toAdd.add(overlap);
}
if (count >= 3) return false;
if (toAdd.size() > 0) list.addAll(toAdd);
list.add(new int[]{start, end});
return true;
}
}
```

]]>```
public char nextGreatestLetter(char[] letters, char target) {
int start = 0 , end = letters.length - 1;
while(start <= end){
int mid = (start + end) / 2;
if(target < letters[mid])
end = mid - 1; // if target is less than mid we go left
else
start = mid + 1;
}
return letters[start % letters.length]; // if start goes beyond the array we wrap around
}
```

]]>```
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
for (int i=0; i < letters.size(); ++i) if (letters[i] > target) return letters[i];
return letters[0];
}
};
```

]]>```
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
return divide(lists, 0, lists.length - 1);
}
private ListNode divide(ListNode[] lists, int start, int end) {
if (start == end) {
return lists[end];
}
int mid = start + (end - start) / 2;
ListNode l1 = divide(lists, start, mid);
ListNode l2 = divide(lists, mid + 1, end);
return merge(l1, l2);
}
private ListNode merge(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val < l2.val) {
l1.next = merge(l1.next, l2);
return l1;
} else {
l2.next = merge(l1, l2.next);
return l2;
}
}
}
```

]]>```
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
int left = 0, right = letters.length-1;
while(left <= right) {
int mid = left + (right-left)/2;
if(letters[mid] <= target) {
left = mid + 1;
} else {
right = mid-1;
}
}
return left >=0 && left < letters.length ? letters[left] : letters[0];
}
}
```

]]>`L`

, based on number of parts `k`

, we can formulate whether an index position `i`

should be a head node of parts:
```
n==0 || (i < m? i%(n+1)==0 : (i-m)%n==0), where n = L/k, m = (L%k)*(n+1)
```

Then we just need to traverse the list to split ONLY at head nodes.

```
vector<ListNode*> splitListToParts(ListNode* root, int k)
{
// get list length
int L = 0; for (auto x = root; x; x = x->next) ++L;
// if node at index i should be a head of part
auto isHead = [&](int i) {
int n = L/k, m = (L%k)*(n+1);
return n==0 || (i < m? i%(n+1)==0 : (i-m)%n==0);
};
vector<ListNode*> parts(k);
int i = 0, j = 0;
for (ListNode *x = root, *p = nullptr; x; p = x, x = x->next)
if (isHead(i++)) { // split list only at part head
parts[j++] = x;
if (p) p->next = nullptr;
}
return parts;
}
```

]]>class Solution {

public int searchInsert(int[] nums, int target) {

int counter = 0;

boolean b = false;

for (int i = 0; i < nums.length; i++){

if (nums[i] == target){

b = true;

counter = i;

}

}

if (b == false){

for (int i = 0; i < nums.length; i++){

if (target > nums[i]){

counter++;

}

}

}

return counter;

}

}

''' ]]>

` if (left.dis + right.dis < res.dis) `

will overflow.
```
class Cell {
int node;
int dis;
boolean found;
public Cell(int node, int dis, boolean flag) {
this.node = node;
this.dis = dis;
found = flag;
}
}
public int findClosestLeaf(TreeNode root, int k) {
Cell res = new Cell(-1, 2000, false);
helper(root, k , res);
return res.node;
}
private Cell helper(TreeNode root, int k, Cell res) {
if (root.left == null && root.right == null) {
if (root.val == k) {
res.node = root.val;
res.dis = 0;
}
return new Cell(root.val, 1, false);
}
Cell left = root.left == null ? new Cell(-1, 2000, false) : helper(root.left, k, res);
Cell right = root.right == null ? new Cell(-1, 2000, false) : helper(root.right, k, res);
if (root.val == k) {
if (res.dis > left.dis) {
res.node = left.node;
res.dis = left.dis;
}
if (res.dis > right.dis) {
res.node = right.node;
res.dis = right.dis;
}
return new Cell(-1, 1, true);
}
if (!left.found && !right.found) {
if (left.dis < right.dis) {
left.dis++;
return left;
} else {
right.dis++;
return right;
}
}
if (left.dis + right.dis < res.dis) {
res.dis = left.dis + right.dis;
res.node = left.found ? right.node : left.node;
}
int distance = left.found ? left.dis + 1 : right.dis + 1;
return new Cell(-1, distance, true);
}
```

]]>```
public int titleToNumber(String s) {
int value = 0;
for(int j=0, i=s.length()-1; i>=0; i--, j++)
value += ((int)Math.pow(26, j) * (s.charAt(i)-'@'));
return value;
}
```

]]>'''

class Solution {

private StringBuilder res = new StringBuilder();

```
public String tree2str(TreeNode t) {
if(t==null) return "";
helper(t);
return res.substring(1, res.length()-1);
}
private void helper(TreeNode t) {
if(t==null) return;
res.append("(" + t.val);
if(t.left==null && t.right != null) {
res.append("()");
}
helper(t.left);
helper(t.right);
res.append (")");
}
```

}

'''

```
public int[] constructRectangle(int area) {
int limit = (int)Math.sqrt(area), width = 1, length = 1;
for(int i = 1; i <= limit; i++) {
if(area % i == 0) {
width = i;
length = area/i;
}
}
return new int[]{length, width};
}
```

]]>