I am assuming the question is: we take some L and R, then we write L, L, L, L+1, L+1, L+1, ...., R, R, R; then we delete one of these numbers and concatenate all of it together into S. We get S and we want to know which number was removed.

Fundamentally, to get a divide and conquer solution, we need to build some expectation of what the string is at some position. If we haven't removed a number on the left half, then when we check the middle, it will match our expectation, and if we have removed a number, it won't. This allows us to divide and conquer.

Building that expectation in small cases is easy. Building it in a general case is extremely hard if you do not have a bound on L: when L is unbounded, it is impossible to distinguish if you are outside the length of L or not. For example, say your string is 4747 4747 4747 4748 4748 4748 4749 ... and you stopped looking. You could be in L = 4747, but you could also be in L = 4747 4747 4747 4748 4748 4748 4749.

When L and R are reasonably bounded, then we can find them relatively quickly by brute force: try the first K digits to be L, and check that we have either (L)(L)(L+1)(L+1)(L+1) or (L)(L)(L)(L+1)(L+1), where this pattern extends enough that together with the bound on L we are sure. (The R case is similar.)

After, we can build a divide and conquer. Suppose we are looking at the interval S[i]...S[j] and it is supposed to represent L, R. Let's see where M = (L+R)//2 is supposed to start assuming the representation of [L, M-1] is untouched. We need to know how many digits are used to write L, L+1, ..., M-1 3 times. Let F(x) be the number of digits used to write 1, 2,..., x: then we want 3*(F(M-1) - F(L-1)), and figuring out F is a classic problem. Afterwards, we can look from S[i + F(x)] on: if it starts with (M)(M)(M+1) [and M-1 is behind us], then we were missing M; if it starts with (M)(M)(M), then we can consider i += F(x) + len( (M)(M)(M) ), and L = M+1; otherwise we can consider j = i + F(x) and R = M-1.

#2

See https://leetcode.com/contest/leetcode-weekly-contest-3/problems/decode-string/

#3

Traverse the tree at the same time. When both trees won't fit in memory, use a merkle hashing technique and compare the hashes of the root. You can find info on that approach here: https://discuss.leetcode.com/post/187289

#4

Standard technique. Let S[r][c] be the sum of the subrectangle from the top left corner to the bottom right corner of (r, c). Then our query is simply query(r1, c1, r2, c2) = S[r2][c2] - S[r1-1][c2] - S[r2][c1-1] + S[r1-1][c1-1]. We can build S slowly by using S[r][c] = S[r-1][c] + S[r][c-1] - S[r-1][c-1].

#5

Every entry (r, c) maps to it's diagonal c-r. For example:

Now perform a bottom up traversal of leaves using a BFS. A leaf has no children. When we process a node (at this point it is a leaf), its parent now has one less child, and if it is a leaf, enqueue. We will visit the nodes in the correct order, and variable depth will tell us where to put the answer.

class Node: def __init__(self, val): self.val = val self.left = None self.right = None def solve(root): num_children = collections.Counter() parent = {} def dfs(node, par = None): if node: num_children[node] = bool(node.left) + bool(node.right) parent[node] = par dfs(node.left, node) dfs(node.right, node) dfs(root) leaves = [(node, 0) for node, num in num_children.iteritems() if num == 0] ans = [] while leaves: node, depth = leaves.pop() while len(ans) <= depth: ans.append([]) ans[depth].append(node.val) par = parent[node] num_children[par] -= 1 if num_children[par] == 0: leaves.append((par, depth+1)) return ans ]]>Flip Rand01Uniform 3 times, and associate each result as follows:

000: 0

001: 1

010: 2

011: 3

100: 4

101: 5

110: 6

111: reflip # R = Rand01Uniform def Rand06Uniform(): while True: roll = 4 * R() + 2 * R() + R() if roll < 7: return roll ]]>

We can write:

A = 10^(k+1) X + 10^k Z + Y

B = 10^k X + Y

where Y < 10^k, Z < 10.

Now look at N % 10.

If it is odd, and k > 0, then N % 10 = (A+B) % 10 = 2Y contradiction. Hence, k = 0, and A = 10X + Z, B = X. In the equation N = 11X + Z, we can try Z = N % 11, and if Z != 10 then there is the only solution X = (N - Z) / 11. If it is even, then we know the last digit of Y up to two choices. For example, if N = 102, then Y%10 is either 1 or 6. If it is 1, then we want to solve the same problem for N = 10 and append 1 to the answers. If it is 6, then we want to solve the same problem for N = (102 - 12) / 10 = 9 and append 6 to the answer. def solve(N): if N == 0: return [(0, 0)] r = N % 10 if r % 2: Z = N % 11 if Z != 10: X = (N - Z) / 11 return [(10 * X + Z, X)] else: choices = [x for x in xrange(10) if 2 * x % 10 == r] ans = [] for choice in choices: N2 = (N - 2 * choice) / 10 for A, B in solve(N2): ans.append((10 * A + choice, 10 * B + choice)) return ans ]]>Let's investigate T^2 A[x]. This is:

min(T A[x-1], T A[x] - 1, T A[x+1])

= min(min(A[x-2], A[x-1]-1, A[x]), min(A[x-1], A[x] - 1, A[x+1]) - 1, min(A[x], A[x+1] - 1, A[x+2]))

= min(A[x-2], A[x-1] - 1, A[x] - 2, A[x+1] - 1, A[x+2]).

We can show by induction or otherwise that:

T^k A[x] = min_{0 <= j <= k} (A[x ± j] - (k-j) )

When T^k A[x] is positive, all of these terms are positive, namely A[x ± j] > k-j for all 0 <= j <= k. Graphically, A contains a pyramid with heights [1, 2, ..., k, k+1, k, ..., 2, 1], and we want to know the largest pyramid contained in A.

If we can know L(x) = the largest k with up-staircase [1, 2, 3, ..., k] that ends at A[x], and R(x) = the largest k with down-staircase [k, k-1, ..., 2, 1] starting at A[x], then the largest pyramid centered at x will have height min(L(x), R(x)), and we can find the maximum over all x. Finding R is similar to finding L, so let's just focus on finding L.

Say L(x) = k, and let's figure out what L(x+1) is.

If A[x] >= k+1, L(x+1) is k+1. If A[x] < k+1, then L(x+1) is A[x].Thus, L(x+1) = min(L(x) + 1, A[x]) is a recursion for L.

Putting that all together:

def solve(A): A = [0] + A + [0] def staircase(A): #L[x] = largest staircase ending at x L = [] for i, u in enumerate(A): L.append(min(L[-1] + 1, u) if i else 0) return L L = staircase(A) R = staircase(A[::-1])[::-1] return max( min(L[i], R[i]) for i in xrange(len(A)) ) + 1 ]]>@appind said in Find the number of Strings:

As you correctly noted, tribonacci doesn't account for having one 'b' in the string. But the code that you quoted does:

return sum([tribo[i] * tribo[n - i - 1] for i in range(n)]) + tribo[n]

The for loop in the code above assumes that there's one 'b' in the string, and the position of 'b' splits the string into two substrings that don't contain a 'b' and therefore we can just use tribonacci for each string and multiply the results.

The last step is just accounting for a string that doesn't contain a 'b' character, and that's just 'tribo[n]'.

I hope this helps you understand my solution better!

This makes sense.

Any clue on how it reconciles intuitively with the solution by @pbg

Using the same approach in E'(n) and combining all terms you can reach a compact solution:

How did @pbg arrive at Ep = ep1 + ep2 +ep3 ?

These two different solutions mean that sum([tribo[i] * tribo[n - i - 1] for i in range(n)])

must equal ep_n-1 +ep_n-2+ep_n-3

What's the intuitive understanding of that as one is × and + over n elements, and other is + of 3 terms ?

Guess AAAA BBBB CCCC DDDD. Your next guess is going to be either EEEE or of the form XXYY. Here, eg. [AAB] denotes that we know there is two A's, one B, no C's, and no D's in the final answer. Let's say +N to mean that we need at most N additional guesses.

When we know there is say, exactly one A and exactly one B, then guessing AABB has 4 states where you get result 0, 4 states where you get result 1, and 4 states where you get result 2, all of which are easy to find ways to distinguish within 2 additional guesses. This is what I mean by "place AB in +3".

[AAAB]: 4 possibilities = +2.

[AAA]: Guess EEEE, then it becomes like [AAAB], so +3.

[AABB]: 6 possibilities = +3.

[AABC]: Guess BBCC, +3.

[AAB]: Guess AABB, +4.

[AA]: Guess EEEE. Now it's like [AABB] or [AABC] which are +3, so answer +4.

[ABCD]: Place AB in +3, now distinguish C and D in +1, answer +4.

[ABC]: Place AB in +3, now find C in +1 and distinguish E/F in +1, so answer +5.

[AB]: Place AB in +3. Now from the remaining places it's the four possibilities EE EF FE FF, so answer +5.

[A]: Guess EEEE. It's either like [AAAB] or [AABC], so answer +4.

[]: Guess EEEE. It's either like [EEEE] (+0), [EEEF] (+2), [EEFF] (+3), so answer +4.

I was starting with a similar approach but this will not work as it will re-reverse the jump pointer for pointers that point to nodes further down the chain. For instance if you had the chain going from 1 -> 2 -> 3 and 1 has a jump pointer to 3, you'll be reversing the jump ptr twice, once at 1 and the second time at 3. Same will apply if there's a ptr going backwards originally (say from 3 to 1 in the example earlier). Once you reverse the list to the state of 1 <- 2 <- 3, you'll again be double reversing the ptr from 3 to 1, once at 3 and the second time at 1. ]]>

First, write recursive function instead of iterative. Code is simple.

Secondly, recursive is a depth first search algorithm, treat it as a graph search algorithm.

Third, I like to argue that "find lowest common ancestor" maybe is a more complicated algorithm. Better not relate to the algorithm "find lowest common ancestor".

To find a path from root node to search node, the function is designed to find one node a time. The time complexity should be the same to find two nodes one time.

Time complexity is O(n), n is the total nodes of binary tree. Use preorder traversal, visit root first, then visit left and right child.

Here is my C# practice code.

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BinarySearchTreeTwoNodesDistance { class Program { internal class Node { public int Value { get; set; } public Node Left { get; set; } public Node Right { get; set; } public Node(int number) { Value = number; } } static void Main(string[] args) { // calculate two nodes distance RunTestcase(); } /// <summary> /// inorder traversal - 1 2 3 4 5 6 7 /// </summary> public static void RunTestcase() { var root = new Node(4); root.Left = new Node(2); root.Left.Left = new Node(1); root.Left.Right = new Node(3); root.Right = new Node(6); root.Right.Left = new Node(5); root.Right.Right = new Node(7); // distance should be 4 var distance = FindDistance(root, root.Left.Right, root.Right.Right); Debug.Assert(distance == 4); var distance2 = FindDistance(root, root.Left.Right, root.Left.Left); Debug.Assert(distance2 == 2); } public static int FindDistance(Node root, Node p, Node q) { IList<Node> possiblePath_1 = new List<Node>(); IList<Node> possiblePath_2 = new List<Node>(); IList<Node> searchPath_1 = new List<Node>(); IList<Node> searchPath_2 = new List<Node>(); FindPath(root, p, possiblePath_1,ref searchPath_1); FindPath(root, q, possiblePath_2,ref searchPath_2); if (searchPath_1.Count == 0 || searchPath_2.Count == 0) { return 0; } // find first node not equal int index = 0; int length1 = searchPath_1.Count; int length2 = searchPath_2.Count; while (index < Math.Min(length1, length2) && searchPath_1[index] == searchPath_2[index]) { index++; } //(length1 - 1) + (length2 - 1) - (2 * (index - 1)) return length1 + length2 - 2 * index; } /// <summary> /// Do a preorder search for the node /// </summary> /// <param name="root"></param> /// <param name="search"></param> /// <param name="possiblePath"></param> /// <param name="searchPath"></param> public static void FindPath(Node root, Node search, IList<Node> possiblePath, ref IList<Node> searchPath) { if (root == null || searchPath.Count > 0) { return; } if (root == search) { searchPath = possiblePath; searchPath.Add(search); return; } possiblePath.Add(root); IList<Node> leftBranch = new List<Node>(possiblePath); IList<Node> rightBranch = new List<Node>(possiblePath); FindPath(root.Left, search, leftBranch, ref searchPath); FindPath(root.Right, search, rightBranch,ref searchPath); } } } ]]>