解题思路

Selection sort

如果有一沓人民币,怎么按照面额从小到大按顺序排序?
答:每次从这沓人民币中取出面额最小的放到一边,循环往复直到原有的这沓人民币被取完就排序完成了。
同理,我们可以循环遍历题目中的数组A每次将最小的element移动到数组A的左边,等for循环执行完之后数组A就是一个排好序的数组了。

Merge sort

1.将数组分成两组
2.每一组各自排序,怎么排?用同样的方法排,重复动作(1)分成两组...(递归)
3.合并:经过1,2动作的递归后,最后会变成一颗树,再从树的最底层开始每两个节点开始合并,
合并的同时做好排序,当合并到最顶层时整个数组就排序好了。
如何排序:每个节点的数据都是由上一次合并后得到的是排序好的!
我们可以把两个节点想象为有两个数组,每次对比两个数组的第一个元素取出较小的元素放到另一个数组里,
当两个数组的元素都被取完了就完成排序和合并了。

Quick sort

快速排序的核心思想:先随机找到一个支点(pivot),找到这个支点在数组中真正的index(排序好后的index),
在寻找index的同时把所有比pivot value小的元素放左边,大于等于pivot的元素放右边;
然后以支点为切口将数组切开成左右两部分(不包含支点),再从这两部分各随机选中一个支点找到其在数组中真正的位置,
循环往复直至无法再切割为止。

寻找pivot index的过程
1.随机确定一个pivot
2.将pivot放到最右边
3.根据随机选中的pivotIndex分区,定义左右挡板(指针):i, j向中间遍历比较ele与pivot ele的大小,
比pivot小的元素放左边,大于等于pivot的元素放右边;
4.最后i就是我们要找的pivotIndex,将最右边的pivot与i互换位置即可

*荷兰旗问题(Rainbow sort)
这种荷兰期问题的核心解法很简单:ijk,ijk,ijk重要的事情说三次,
为什么是ijk呢,因为解这种问题需要定义3个指针配合运算,
[0,i)i左边的元素都是-1,
[i,j)中间的元素都是0,
(k, arr.length-1] k右边的元素的都是1,

递归(Recursion)

递归三部曲

1.define subproblem:定义子问题
2.find recursion rule: 找出递归规则
3.define base case: 定义退出条件

知识点

  1. 表象上: function calls itself
  2. 实质上: reduce a big problem to smaller ones(size n depends on size n-1, or size n-2 or n/2...)
  3. implementation上:
    1).base case: smallest problem to solve
    2).Recursive rule. how to make the problem smaller
    (if we can resolve the same problem but with a smaller size,
    then what is left to do for the current problem size n)

Binary Search

Essentially, the principle of binary search is reduce the search space by 1/2 of its
original size. In the meantime, you must guarantee that the target must not be ruled out.
核心思想:每次淘汰一定不对的元素

前提:二分查找算法所处理的数组必须是Sorted好的
二分查找又称为折半查找,仅适用于事先已经排好序的顺序表。
其查找的基本思路:首先将给定值K,与表中中间位置元素的关键字比较,若相等,
返回该元素的存储位置;若不等,这所需查找的元素只能在中间数据以外的前半部分或后半部分中。
然后在缩小的范围中继续进行同样的查找。如此反复直到找到为止。

中心开花等解法

Queue Stack

Question:How to use multiple Stacks to implement a de-queue
Method: Use 3 stacks to improve the time compleity of pop() operation.
We use a buffer stack, say stack3 to buffer the element, when moving all elements
from left part to right part.To make sure the number of elements in Left and Right part are
roughly 50% of all element.In detail, Stack3 is used as the buffer to store the top 1/2 element,
so that the bottom 1/2 element can be moved to stack2.

worst case amortized time= ??
step1:we move 1/2n ele from stack2 to stack3(buffer)
1/2
n + 1/2n = n
step2:we move the remaining 1/2 ele from stack2 to stack1(from right to left)
1/2
n+1/2n = n
step3:reverse step1,
1/2
n+1/2*n = n
So, In order to blance both sides, it takes O(3n) for n element.
All the flowing pop operation, take only O(1)
xxxxxx(n/2) ||stack1 stack2||yyyyyy(n/2)

                        3n+n/2*1      3.5n
For 1st n/2 elements ------------- = ------ = O(7) = O(1)
                          n/2         0.5n
                          
                        3n+n'/2*1     3.5n'
For 2st n/4 elements ------------- = ------ = O(7) = O(1)  n'=n/2
                          n'/2        0.5n'

                        3n''+n''/2*1  3.5n''
For 3st n/4 elements ------------- = ------ = O(7) = O(1)   n'=n/2
                          n''/2       0.5n''
        
            3.5n + 3.5n*1/2 + 3.5n*1/4 + ....       3.5n(1+1/2+1/4+...)
total = --------------------------------------- = --------------------- 3.5* 2 = O(7)
                        n                                   n

1.什么问题要往stack上考虑?
anwser:从左到右linear scan一个array/string时,如果要不断回头看左边最新的元素时,
往往要用到stack
1.histogram中找最大长方形
2.逆波兰表达式
3.String的repeatedly dedduplication. cabba->caa->c
2.Stack的移动操作有什么常见特性?
1.将stack1所有元素全部move到stack2,元素在stack2的顺序完全reverse
2.将stack1所有元素move到stack2,然后元素全部(或者部分)move回stack1,则
回到原来stack1的元素的顺序不变, amortized的时间复杂度分摊到每一个move的元素的时间为O(1)

LinkedList

Key points
1.When you want to de-reference a ListNode, make sure it is not a Null pointer
2.Never ever lost the control of the head pointer of the LinkedList.

Binary Tree & Binary Search Tree

基本知识点:
tree traverse
1.pre-order
2.in-order
3.post-order
trick:base case usually refers to the null ChildNode below the leaf node.
(null pointer under the leaf node)

基本概念:
1.Balanced binary tree: is commonly deefined as a binary tree in which the depth of the
left and right subtrees of every node differ by 1 or less
Conclusion 1:If a tree has n number of nodes. and it is balanced,
then the height(level) of the tree = O(lgn)

2.Complete binary tree: is a binary tree in which every level, except possibly the last,
is completely filled, and all nodes are as far left as possible.
Conclusion 2:If a tree is a complete tree, then it must be a balanced tree.

3.Binary Search Tree: for every single node in the tree, the values in its left subtree
are all smaller than its value, and the values in its right subtree are all larger than its value.
Conclusion 3:If we print the value of the nodes in BST in in-order sequence,then it must form an ascending order.

Recursion在tree题目的基本应用大致分为2类
1.把value从上往下传递(then从下往上)的题目
1.1 BST判顶方法
2.只把value从下往上传递
2.1 getHeight(Node root) 是把integer value 从下往上传递
2.2 isBalanced(Node root)是把boolean value 从下往上传递
2.3 isSymmetric(Node root)是把boolean value 从下往上传递
2.4 assign the value of each node to be the total number of nodes that belong to its left subtree
(是把integer value从下往上传递的题目)

Heap & Graph Search Algorithms I

性质:heap的实现通过构造二叉堆(binary heap),这种数据结构具有以下性质

  1. heap总是一颗完全树. complete binary tree
  2. 任意节点小于它的所有后裔,最小元素在堆的根上(堆序性).
  3. 将根节点最大的堆叫做MAX HEAP,根节点最小的堆叫做Min Heap
  4. index of lChild = index of parent*2 + 1
  5. index of rChild = index of parent*2 + 2
  6. index of parent = (index of child-1)/2 (integer divsion)
  7. unsorted but fpllpw rules above
    支持的基本操作
  8. insert: 向堆插入一个新元素,复杂度O(lgn) 插入到heap的最后一个index,再跟parent节点比较,比parent小就往上冒泡
  9. update(index): 将新元素提升使其符合堆的性质;时间复杂度O(lgn)
  10. get/peek: 获取当前heap顶部元素的值 O(1)
  11. pop:删除堆顶元素,T=O(lgn), 删除第一个index,再将最后一个元素移到顶部,再往下压与较小的子节点交换,直到没有比它小的节点
  12. heapify: 堆化,使一个unsorted array变成一个堆O(n)

Graph & BFS
trick: Queue while{poll} for{offer}
Breadth First Search(BFS1)
BFS1的操作过程&How to describe a BFS's action during an interview?
1.Definition 1: expand a node;中文: 延展一个node, e.g. visit/print its value...
2.Definition 2: generate node's neighbor node:earch out to its neighboring node
(First, to generate Node 3, and then generate Node 2).
3.Data Stucture: Maintain a FIFO queue, put all generated nodes in the queue.
e.g. 3 and then 2 into the queue(FIFO) queue head->[3, 2] tail
4.Termination condition: do a loop until the queue is empty
5.Process
When should we consider to use breadth first search?
Deal with relationship between nodes on the same level.Especially in a tree.
Best First Search(BFS2)
1.Objective: 由点到面 == 所有点的最短距离算法
2.Example problem: 从北京到中国其他主要城市的最短距离各是多少
3.Data structure: priority queue(min heap or max heap)
4.解题思路
4.1 Inital state(start node)
4.2 Node expansion/Generation rule:
4.2.1 expand the node x with xxxxxx
4.2.2 generate the neighbors (y) of this node
4.3 Termination condition:所有点都计算完毕才停止,也就是priorityqueue变空

properties
1.one node can be expanded once and only once
2.one node can be generated more than once.(cost can be reduced over time)
3.all the cost of the nodes that are expanded are monotonically non-decreasing
(所有从priority queue里面pop出来的元素的值是单调非递减-->单调递增)
4.for a graph with n nodes and m edges, time complexity is O(mlogn)
5.when a node is popped out for expansion,its value is fixed which is equal to
the shortest distance from the start node.

DFS

Depth-First Search:
1.DFS一般用来计算有多少种排列组合的问题.
2.Recall "using pre-order to traverse a tree"
3.实现方法:easy to use recursion
4.常见考题
* print all subsets of a set
* Given a string with no duplicate characters,
return a list with all permutations of the characters. (swap call swap)
* print all valid permutaions of () () ()
* 99cents 凑硬币金额,有1分,5分,10分,25分coin,给定一个钱数99cent,有多少种组成方式
并打印出所有的可能组合.

DFS基本方法:完成一件事情需要N个步骤,每个步骤有M种选择
1.what does it store on each level?
(每层代表什么意义?一般来讲解题之前就能推断出DFS要recurse多少层)
2.How many different states should we try to put on this level?
(每层有多少个状态/case 需要try? 每层叉出多少个叉)

DFS复杂度分析:
Using revursion tree to get the complexity

of levels

of branches for each node

use the # of nodes of last level to represent the # of nodes in the whole tree.

String I

5类常见问题:(和array的某些问题相似,往往需要2个index来完成操作.)

  1. Removal
    1.1 remove some particular chars from a string
    1.2 remove all leading/trailing/duplicated empty spaces from a string.
  2. De-duplication aaabbb_ccc->ab_c
    3.Substring
    3.1 regular method
    3.2 robin-carp (hash based string matching) & KMP (Knuth-Morris-Pratt)
    4.String replacement:replace empty space ‘ ‘ with "%20"
    5 Reversal(swap) e.g. I Love Google-> Google Love I

Advanced operation (Defer to String II)

  1. Move letter around e.g. ABCD1234->A1B2C3D4
  2. Permutation (use DFS)
  3. Decoding/encoding aaaabcc->a4b1c2
  4. Longest substring that contains only unique chars
  5. Matching(*,?)
  6. etc

解题思路:
挡板大法1:
1.两个挡板,相向而行
2.2个挡板,3个区域,同向而行
Initialization
i=0; all letters to the left-hand side of i(not including i) are all processed letters
that should not be removed(slow)
j=0; j is the current index to move(fast). all letters in [i, j] are all area that we do not care(empty space xxx)
(j, size-1] unknown area to explore
3.sliding window in a string (slow=fast indices)
slow:
fast:

Bit

Bit Operation

&
|
~
^
<<
>>
>>>

Q1: determine whether a number x is a power of 2
Q2: How to determine the number of bits that are different between two positive integer?
Q3: What happens if we assign a negative to an unsigned integer?
Q4: determine whether a string contains unique characters(i.e. no duplication)
Q5: How to reverse all bits of a number?
Q6: Given a number x, how to get the hexadecimal representation of the number in string type?

OOD II

Polymorphism

Recursion II

Q1 a^b
Q2 Recursion与1D or 2D array的结合
1.1D array 二分法比较常见
1.1 MergeSort
1.2 QuickSort
2. 2D Array
2.1 逐曾(row by row)递归: n queen
Q3. Recursion与LinkedList的结合
Q3.2 Reverse a Linked list(pair by pair)
Q4. Recursion与String的结合
Q4.1 reverse a string using recursion
Q4.2
Q5. Recursion与Tree的结合
Q5.1 Tree+Recursion:从下往上返值
way of thinking(Tricks)
1.What do you expect from your lchild / rchild?
(usually it is the return type of the recursion function)
2.What do you want to do in the current layer?
3.What do you want to report to your parent?(same as Q1=Q3)

Dynamic Programming I

DP的核心思想类似数学归纳法

  1. 把一个大问题(size==n)的解决方案用比他小的问题(问题们)来解决,也就是思考从问题
    size=n-1 增加到size=n的时候,如何用小问题的solution构建大问题的solution.

2.与 Recursion的关系:
2.1 Recursion从大到小来解决问题,不记录任何sub-solution只要考虑
2.1.1 sub problem
2.1.2 base case
2.1.3 recursive rule
2.2 DP从小到大来解决问题,不记录任何sub-solution只要考虑
2.2.1 由size(<n)的subsolution(s)-> size(n)的solution
2.2.2 base case
2.2.3 Induction rule

DP的解题常用方法:
适合什么类型的问题:
1.一维的original data (such as a rope, a word, a piece of wood),求MAX or MIN (cut, merge, etc)
1.1 if the weight of each smallest element in the original data is identical/similar
1.1.1 e.g. identical: 1 meter of rope
1.1.2 e.g. similar. a letter, a number
Then this kind of problem is usually:
Linear scan and look back to the previous elements.
For example:
Longest Ascending Subarray (when at i, look back at i-1)
Longest Asending Subsequence (when at i, look back at 1......i-1)
1.2 if the wight are not the same:
1.2.1 e.g. DP1课后题 沙子归并
1.2.2 e.g. 强化练习:切木头
从中心开花,[index=0,1,2,3,n-1], for each M[i,j], we usually need to try out all possible k that (i<k<j), M[i,j] = max(M[i,k]+/-* M[k,j]) for all possible k)

  1. (稍微复杂)二维的original data(such as two words 求 longest common substring; 2D matrix求最大sub-matrix和最大)
    思路:
    1. Base case:
      DP[0] = ?
    2. Induction rule:
      a.DP[i] represents what ???
      DP[i] represents ....
      b.DP[i] = 数学表达式,与小一号或小两号问题扯上关系

左大段右小段 etc

OOD II

Parking Lot
1.Understand/Analyze the use case(明确这个系统是干什么的)
    Usecase --> APIS
2.Classes and thir relationships
    Association: ageneral binary relationship that describes an activity between two classes.
    Aggregation/Composition:a special form of association, which represents an ownership relationship between two ckasses(has-a)
    Inheritance: is a

DP II

Q1 Minimum Number of Jumps
Q2 Largest sum of a subarray. T=O(n) S=O(n)
Follow up1: how to optimize space
Follow up2:how to return the left-right border of the solution?
Q3 Dictionary word problem
Q4 Edit Distance
DFS、DP
Q5 Largest square of 1's in binary matrix

Element deduplication/removal in an array

1.同向而行隔板题:
a.基本思想: 用两个变量,一个变量记录当前指针位置(= fast index), 一个变量记录隔板位置(= slow index).
b.性质1:slow隔板左边时处理好的元素,当前指针fast右边是未处理的元素,隔板和当前指针之间的区域时无用的元素,每次只要分析当前元素性质是否要加入或者移动slow隔板就可以了。
c.性质2:用快慢两个指针,同向而行,处理完毕后,return的结果中,每个Integer/char的相对位置不变。
Prerequlsite: We need to ensure the fast poiter is always ahead of the slow pointer.
关键点: 每个隔板的物理意义在整个程序运行过程中都要保持consistent.

Data structure:
fast index: the current position of the linear scan slow index A[0, slow-1] is the answer for A[0, fast-1]

  1. 隔板, 相向而行,Two pointers moving in opposite direction
    a.基本思想:用两个变量,一个变量记录左边隔板位置(=left index), 一个变量记录右边隔板位置(= right index)
    b.性质1: left左边是处理好的元素, right右边也是处理好的元素,两个隔板中间是未处理区域。
    c.性质2: 处理完毕之后, return的结果中, 每个integer/char的相对位置可能发生变化。

推荐阅读更多精彩内容