Heap is a complete binary tree represented by an array. A binary tree is one kind of tree, every parent node has at most two children, we call them left-subtree and right-subtree.

A perfect binary tree is a binary tree when the layer count is k, it has 2^{k}-1 nodes. Like this:

And we can think a complete binary tree is a perfect binary tree leak or not lack some nodes but must fill the nodes from top to bottom, left to right. It means only can lack some nodes from the right. Like this:

When we use a heap to store this complete binary tree, we can save it as an array like this: [A, B, C, D, E, F, G, H, I, J, K, L]. Use this storage method, we will find out that the index of the root of this tree is 1.

And the index of every parent node is the children node’s index divide to 2. And left sub-node’s index is its parent node’s index multiply 2, right sub-node’s index is its parent node’s index multiply 2 then add 1.

So we get the function to access children and parent nodes.

Then we discuss a data structure, Max-Heap. It is a heap, every parent bigger than its children. So we know in a Max-Heap root is the biggest number. The picture is a Max-Heap and its corresponding array.

You can easy define a Min-Heap, we don’t discuss it now.

If a node of a ** max-heap** smaller than its sub-nodes, it violates the rule of max-heap. If we know its sub-nodes is valid max-heap, we can correct it by a

We make a video demo, 4 is the error node.

This is the code. _A is the array store the heap, and index -1 because in Java array’s index start from 0:

For the Max-Heapify to run, we write a helper function exchange:

Then how can we build a Max-heap from a random complete binary tree? Suppose we have a heap like this:

We can start from the middle of the heap (the 5th node), back to root one by one to perform the max-heapify operation. When it finished, we have a max-heap. This is a demo video for this:

Code like this:

When we look carefully we will find out max-heap is not an ordered data structure. Every parent node is larger than its children, but left sub-node can bigger also can smaller than the right sub-node. We can’t easily get an ordered array just by traverse the binary tree in any way. So how do we use a heap to sort numbers?

We know the root always is the biggest one. So we can swap the root with the last node, then remove the last node from the heap, and max-heapify the root. Then the remaining heap becomes a valid max-heap, we can do this again and again. We always put the largest number at back, so we get an ordered array.

We can start from this max-heap to sort.

And this is our demo video:

Code like this:

And max-heap can support an operation ** ExtractMax**, return the root, remove it, and shrink the heap. We can use it to get the maximum number or the k largest number without sort it first. Code like this:

So we can use max-heap to sort numbers. Or we can use it to get the maximum number or get the k largest number to pay less cost than sort it.

GitHub address：https://github.com/tinyfool/leetcode/blob/master/src/CLRS/HeapSort.java

Write an efficient algorithm that searches for a value in an *m* x *n* matrix. This matrix has the following properties:

- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.

**Example:**

Consider the following matrix:

[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]

Given target = `5`

, return `true`

.

Given target = `20`

, return `false`

.

This problem we tried 4 solutions, ** vertical and “horizontal binary search”** approach,

This is a direct approach, is a divide and conquer way. First, we cut the matrix vertically to the ** top** and

Running time is 52ms, not fast enough. This because we only use one property of the matrix, ** ascending from left to right**, we didn’t use the property of

We need to use binary search in both ways to be faster. When we cut the matrix, we can find out two key points, one is the ** right-bottom** corner

In the code ** p1** is

Running time is 27ms still not fast enough.

I know we can split the matrix into 4 areas to search, but I try to avoid this way. Because code will be really messy. Now we know last way is not fast enough, I have to code in this way. It is not complex to think, cut the matrix into 4 areas, then cut and cut, until there is only one element. We can use the key points (every left-top and right bottom corner of sub-matrixes) to seep up searches.

This thought is not hard, but the code is very complex. You may already find out this is very similar to ** Strassen’s algorithm for matrix multiplication** from Introduction to Algorithms. This is the code:

Running time is 7ms is fast enough.

All these solutions are too complex, can we solve it easily? I tried once expend the matrix to an array, then use a binary search. But I find out the matrix ascending from left to right and ascending from top to bottom, don’t mean it can expend to an ordered array. So directly use a binary search will not get the correct result.

So we only can expend the matrix to an array, and sort it, then use a binary search. The code like this:

Code is very simple but very slow, running time is 610ms, is not very useful. The 4 area solution is best.

Github 地址：https://github.com/tinyfool/leetcode/tree/master/src/p0240

Want to know details of the Divide and conquer, check my post: Leetcode problems of Divide and conquer.

Given an array of size *n*, find the majority element. The majority element is the element that appears **more than** `⌊ n/2 ⌋`

times.

You may assume that the array is non-empty and the majority element always exists in the array.

**Example 1:**

Input:[3,2,3]Output:3

**Example 2:**

Input:[2,2,1,1,1,2,2]Output:2

We provide 3 solutions. ** Hash-map** approach,

This solution is easily understood, we use a hash-map to store counts of elements. The first loop we count every element. The second loop we find the most frequency element, it is our result. Actually, we can use one loop to get the result, a little faster, but it will not change the complexity, so we ignore it.

Because the majority element appears more than half times, so we know if we split the array to ** left** and

First, we sort the array, then one loop to count elements. (And there are a more easy solution, sort and get the middle element, it must be the majority element.)

Github address: https://github.com/tinyfool/leetcode/tree/master/src/p0169

Want to know details of the Divide and conquer, check my post: Leetcode problems of Divide and conquer.

Given an integer array `nums`

, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

**Example:**

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

**Follow up:**

If you have figured out the O(*n*) solution, try coding another solution using the divide and conquer approach, which is more subtle.

Actually, this problem is the same problem as the ** Maximum Subarray problem** from

Github address：https://github.com/tinyfool/leetcode/tree/master/src/p0053

Want to know details of the Divide and conquer, check my post: Leetcode problems of Divide and conquer.

Merge *k* sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

**Example:**

Input:

[

1->4->5,

1->3->4,

2->6

]Output:

1->1->2->3->4->4->5->6

I don’t know how to merge k lists, but we know how to merge two lists from problem 21. So we can merge the first two lists and merge others one by one. This is the brute force solution.

* mergeTwoList* function from problem 21.

How to use ** Divide and conquer** approach to solve this problem? We can naturally think about divide the lists to two half, then divide it again and again, until there are only two linked lists. Then we can use the

In this solution we use a min-heap, it is almost identical to max-heap. We only need to change serval lines to make a max-heap to become min-heap. We use the code described in “Heap and Heap-Sort algorithm“.

Our method is: First, move all data from lists to an array, then use the array to build a min-heap. Finally, we output the current minimum number in a loop, make a LinkedList and return it.

This is the code (Code about min-heap you can find in GitHub files):

Github address: https://github.com/tinyfool/leetcode/tree/master/src/p0023

Want to know detail of heap and heapsort, check my post:Heap and Heap-Sort algorithm.

]]>** Divide and conquer** is a method to solve a complex problem. When we think of a problem too complex or too big, we can try to divide the problem to some easy problems or small problems. Then we try to solve these small/easy problems and combine the results to solve the complex/big problem.

Divide and conquer is easy when you can easily find out how to divide a problem. But a lot of times how to divide a problem is hard. And different problem always needs a different divide approach. So if you want to master all divide and conquer problems you need to do a lot of practices. Only this way you can build a strong understanding of the thought of divide and conquer, and get more feeling of familiarity, and master more method to divide.

Chapter 2.3.1 of * Introduction to Algorithms* introduces

I implement these three algorithms from pseudocode from the book to Java code:

GitHub address：https://github.com/tinyfool/leetcode/blob/master/src/CLRS/DivideAndConquer/MergeSort.java

GitHub address：https://github.com/tinyfool/leetcode/blob/master/src/CLRS/DivideAndConquer/MaximumSubarray.java

GitHub address：https://github.com/tinyfool/leetcode/blob/master/src/CLRS/DivideAndConquer/SquareMatrixMultiply.java

**Helper functions**

**Matrix split and combine functions **

**Matrix add and minus functions**

**Strassen’s algorithm for matrix multiplication**

4 | Median of Two Sorted Arrays | Hard |

23 | Merge k Sorted Lists | Hard |

53 | Maximum Subarray | Easy |

169 | Majority Element | Easy |

215 | Kth Largest Element in an Array | Medium |

218 | The Skyline Problem | Hard |

240 | Search a 2D Matrix II | Medium |

241 | Different Ways to Add Parentheses | Medium |

282 | Expression Add Operators | Hard |

312 | Burst Balloons | Hard |

315 | Count of Smaller Numbers After Self | Hard |

327 | Count of Range Sum | Hard |

493 | Reverse Pairs | Hard |

514 | Freedom Trail | Hard |

426 | Convert Binary Search Tree to Sorted Doubly Linked List | Medium |

903 | Valid Permutations for DI Sequence | Hard |

932 | Beautiful Array | Medium |

973 | K Closest Points to Origin |

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

**Example:**

Input:1->2->4, 1->3->4Output:1->1->2->3->4->4

This problem has a straightforward approach. We can traverse both linked lists at the same time. Every turn we choose the smaller one and move the corresponding linked list to the next node. In the process, if one of linked list is empty, then put another linked list to the tail of the result linked list.

This is the code:

And we can use recursion to make the code easier and clearer. First, if one of linked list is empty, then return another linked list. Then if the current first node of l1 is smaller than or equal with l2, we change the second node of l1 to the result of the origin second node of l1 merge with l2, vice-versa.

code download url：https://github.com/tinyfool/leetcode/tree/master/src/p0021

Given an array `A`

of positive integers, call a (contiguous, not necessarily distinct) subarray of `A`

*good* if the number of different integers in that subarray is exactly `K`

.

(For example, `[1,2,3,1,2]`

has `3`

different integers: `1`

, `2`

, and `3`

.)

Return the number of good subarrays of `A`

.

**Example 1:**

Input:A = [1,2,1,2,3], K = 2Output:7Explanation:Subarrays formed with exactly 2 different integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].

**Example 2:**

Input:A = [1,2,1,3,4], K = 3Output:3Explanation:Subarrays formed with exactly 3 different integers: [1,2,1,3], [2,1,3], [1,3,4].

**Note:**

`1 <= A.length <= 20000`

`1 <= A[i] <= A.length`

`1 <= K <= A.length`

This problem is very hard if you want to use one sliding window to solve it. But we can use two sliding windows to make it easy to solve.

First, we can easily to implement a sliding window to get a result of the number of different integers in that subarray is equal to or smaller than ** K**.

Then subarraysWithMostKDistinct(k) – subarraysWithMostKDistinct(k-1) will get the result of the number of different integers in that subarray is exactly ** K**.

Then we got the final function ** subarraysWithKDistinct**.

And aonther approach.

Code download address: https://github.com/tinyfool/leetcode/tree/master/src/p0992

Want to know details of the sliding window algorithm, check my post: The Sliding Window Algorithm for string and array.

]]>Given two strings **s1** and **s2**, write a function to return true if **s2** contains the permutation of **s1**. In other words, one of the first string’s permutations is the **substring** of the second string.

**Example 1:**

Input:

s1 = “ab”

s2 = “eidbaooo”Output:TrueExplanation:s2 contains one permutation of s1 (“ba”).

**Example 2:**

Input:

s1= “ab”

s2 = “eidboaoo”Output:False

**Note:**

- The input strings only contain lower case letters.
- The length of both given strings is in the range [1, 10,000].

After reading the request, you will find out this problem is almost the same as problem 438. The word ** permutation** is the same as the word

Code download address: https://github.com/tinyfool/leetcode/tree/master/src/p0567

Want to know details of the sliding window algorithm, check my post: The Sliding Window Algorithm for string and array.

]]>Given a string **s** and a **non-empty** string **p**, find all the start indices of **p**‘s anagrams in **s**.

Strings consists of lowercase English letters only and the length of both strings **s** and **p** will not be larger than 20,100.

The order of output does not matter.

**Example 1:**

Input:

s: “cbaebabacd”

p: “abc”Output:[0, 6]Explanation:

The substring with start index = 0 is “cba”, which is an anagram of “abc”.

The substring with start index = 6 is “bac”, which is an anagram of “abc”.

**Example 2:**

Input:

s: “abab”

p: “ab”Output:[0, 1, 2]Explanation:

The substring with start index = 0 is “ab”, which is an anagram of “ab”.

The substring with start index = 1 is “ba”, which is an anagram of “ab”.

The substring with start index = 2 is “ab”, which is an anagram of “ab”.

This problem is familiar with problem 76. And because the length of the anagram is equal with the origin string, this is a fix-width sliding window problem.

We can copy codes from problem 76 only change serval lines.

This is the code.

Running time is 6ms.

Code download address: https://github.com/tinyfool/leetcode/tree/master/src/p0438

Want to know details of the sliding window algorithm, check my post: The Sliding Window Algorithm for string and array.