【2019春招準備:常見演算法題1-10】
阿新 • • 發佈:2018-12-30
【內容】
- topK
- 臺階
- 非遞迴遍歷二叉樹
【補充】
==================
1.topK
2.青蛙跳臺階
【@深信服 大資料開發】
【題目描述 】
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
【解1】
根據上述測試用例及結果,差不多已經可以看出來一些規律了。
但是這裡再進行一細節方面的分析:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2階一次跳2階的次數。
f(3) = f(3-1) + f(3-2) + f(3-3)
…
f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
由上述可推匯出:
f(n-1) = f(0) + f(1) + f(2) + f(3) + … + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + … + f(n-2) + f(n-1) = f(n-1) + f(n-1)
則可以得出最終結論,在n階臺階,一次有1、2、…n階的跳的方式時,總得跳法為:
f(n) = 0 ,(n=0 )
f(n) = 1 ,(n=1 )
f(n) = 2*f(n-1),(n>=2)
以上,可以看出,若臺階大於0的話,青蛙跳的方法共有2(n-1)種。
【解2】
鳥瞰整個階梯,除開最後一級臺階(n),每一個臺階都有跳或者不跳的可能。
3. 非遞迴遍歷二叉樹
package q2_tree;
import java.util.LinkedList;
import java.util.Random;
/**
* 二叉樹的非遞迴遍歷 linkedList的push(addFirst)是加在頭部,pop也是弄出頭部元素
*
* @author ziboris
* @date 2018年12月22日 下午2:31:31
*
*/
public class Test3_noRecurseTree {
// 自己是一個BinaryTree
// 隨機生成樹:左節點還是右節點
private static final Random rand = new Random();
/*
* 葉子節點
*/
private static class BinaryNode {
int ele;
BinaryNode left;
BinaryNode right;
boolean isFirst;// 專門給後序非遞迴遍歷判定的時候用,判定是否已經訪問過
public BinaryNode(int ele) {
this.ele = ele;
this.left = this.right = null;
this.isFirst = false;
}
}
private BinaryNode root;// 根節點
/*
* 固定元素隨機形狀建樹
*/
private void buildTree() {
int[] nodes = { 3, 0, 7, 4, 9, 10, 45 };
for (int i : nodes) {
insert(i);
}
}
private BinaryNode insert(int ele) {
return root = insert(root, ele);
}
private BinaryNode insert(BinaryNode root, int ele) {
if (null == root) {
return root = new BinaryNode(ele);
}
if (rand.nextInt() % 2 == 0)
root.left = insert(root.left, ele);
else
root.right = insert(root.right, ele);
return root;
}
// #=====================================================================
// #====================== pre ======================
// #=====================================================================
public void preOrder() {
preorder(root);
}
private void preorder(BinaryNode root) {
if (root == null) {
return;
}
System.out.print(root.ele + " ");
preorder(root.left);
preorder(root.right);
}
public void nonRecurPreTraverse() {
if (null == root)
return;
nonRecurPreTraverse(root);
}
private void nonRecurPreTraverse(BinaryNode root) {
LinkedList<BinaryNode> stack = new LinkedList<Test3_noRecurseTree.BinaryNode>();
BinaryNode currentNode, tmp;
currentNode = root;
while (currentNode != null || !stack.isEmpty()) {// stack空了或者當前節點為空結束遍歷
while (currentNode != null) {
System.out.print(currentNode.ele + " ");
stack.push(currentNode);
currentNode = currentNode.left;
}
if (!stack.isEmpty()) {
tmp = stack.pop();
currentNode = tmp.right;
}
}
}
// #=====================================================================
// #====================== in ======================
// #=====================================================================
public void inOrder() {
inorder(root);
}
private void inorder(BinaryNode root) {
if (root == null) {
return;
}
inorder(root.left);
System.out.print(root.ele + " ");
inorder(root.right);
}
public void nonRecurInTraverse() {
if (null == root)
return;
nonRecurInTraverse(root);
}
private void nonRecurInTraverse(BinaryNode root) {
LinkedList<BinaryNode> stack = new LinkedList<Test3_noRecurseTree.BinaryNode>();
BinaryNode currentNode, tmp;
currentNode = root;
while (currentNode != null || !stack.isEmpty()) {
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}
if (!stack.isEmpty()) {
// 理解成將越左下角的節點放在stack的頂端,首先pop出來展示,然後是root節點,最後剩下右邊的節點
tmp = stack.pop();
System.out.print(tmp.ele + " ");
currentNode = tmp.right;
}
}
}
// #=====================================================================
// #====================== post ======================
// #=====================================================================
public void postOrder() {
postorder(root);
}
private void postorder(BinaryNode root) {
if (root == null) {
return;
}
postorder(root.left);
postorder(root.right);
System.out.print(root.ele + " ");
}
public void nonRecurPostTraverse() {
if (root == null)
return;
nonRecurPostTraverse(root);
}
private void nonRecurPostTraverse(BinaryNode root) {
LinkedList<BinaryNode> stack = new LinkedList<Test3_noRecurseTree.BinaryNode>();
BinaryNode currentNode, tmp;
currentNode = root;
while (currentNode != null && !stack.isEmpty()) {
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}
if (!stack.isEmpty()) {
tmp = stack.getFirst();
if (tmp.isFirst == false) {
tmp.isFirst = true;
currentNode = tmp.right;
} else {
tmp = stack.pop();
System.out.print(tmp.ele + " ");
}
}
}
}
/*
* MainTest=-=================================================================
*/
public static void main(String[] args) {
Test3_noRecurseTree mbt = new Test3_noRecurseTree();
mbt.buildTree();
System.out.println("========pre order:=========");
mbt.preOrder();
System.out.println();
mbt.nonRecurPreTraverse();
System.out.println("\n========in order:=========");
mbt.inOrder();
System.out.println();
mbt.nonRecurInTraverse();
System.out.println("\n========post order:=========");
mbt.postOrder();
System.out.println();
mbt.nonRecurPostTraverse();
}
}