假如二維數組爲 {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
同時查找的值爲15
。html
16
次。代碼以下private boolean lookUpInTwoDimensionalArrays(int[][] a, int num) {
// 至少保證 長度至少爲1,且還有元素,
if (a == null || a.length < 1 || a[0].length < 1) {
return false;
}
int b = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
b++;
if (num == a[i][j]) {
// 一共循環多少次:12
System.out.println(TAG + "一共循環多少次:" + b);
return true;
}
}
}
return false;
}
複製代碼
最終的代碼以下node
/**
* 數組是遞增的 ,從左到右 從上到下,那麼數組必定是個正方形的樣子
*
* @param arr 原始的數組
* @param num 須要查找的數字
* @return 是否找到了
*/
private boolean newLookUpInTwoDimensionalArrays(int[][] arr, int num) {
if (arr == null || arr.length < 1 || arr[0].length < 1) {
return false;
}
int rowTotal = arr.length;// 數組的行數
int colTolal = arr[0].length;// 數組的列數
//開始的角標
int row = 0;
int col = colTolal - 1;
int i = 0;
while (row >= 0 && row < rowTotal && col >= 0 && col < colTolal) {
// 是二維數組的 arr[0][arr[0].length-1] 的值,就是最右邊的值
i++;
if (arr[row][col] == num) {
System.out.println(TAG + "newLookUpInTwoDimensionalArrays 執行了多少次" + i);
return true;
} else if (arr[row][col] > num) {// 若是找到的值 比目標的值大的話,就把查找的列數減去1
col--;//列數減去1 ,表明向左移動
} else {// 比目標的num大的,就把行數加上1,而後往下移動
row++;
}
}
return false;
}
複製代碼
15
,那麼舊的代碼會執行15
次,新的代碼只會執行3
次。public char[] replaceBlank(char[] string, int usedLength) {
// 判斷輸入是否合法
System.out.println(TAG+"string.length="+string.length);
System.out.println(TAG+"usedLength="+usedLength);
if (string == null || string.length < usedLength) {
return null;
}
// 統計字符數組中的空白字符數
int whiteCount = 0;
for (int i = 0; i < usedLength; i++) {
if (string[i] == ' ') {
whiteCount++;
}
}
// 若是沒有空白字符就不用處理
if (whiteCount == 0) {
return string;
}
// 計算轉換後的字符長度是多少
int targetLength = whiteCount * 2 + usedLength;
//新的保存的字符串的數組
char[] newChars = new char[targetLength];
int tmp = targetLength; // 保存長度結果用於返回
// if (targetLength > string.length) { // 若是轉換後的長度大於數組的最大長度,直接返回失敗
// return -1;
// }
// todo 必須先作 這個,注意體會 --i 和 i-- 的區別
usedLength--; // 從後向前,第一個開始處理的字符
targetLength--; // 處理後的字符放置的位置
// 字符中有空白字符,一直處理到全部的空白字符處理完
while (usedLength >= 0 && usedLength < targetLength) {
// 如是當前字符是空白字符,進行"%20"替換
if (string[usedLength--] == ' ') {
newChars[targetLength--] = '0';
newChars[targetLength--] = '2';
newChars[targetLength--] = '%';
} else { // 不然移動字符
newChars[targetLength--] = string[usedLength];
}
usedLength--;
}
return newChars;
}
複製代碼
private String idoWorkReplace(String str, String tagStr) {
if (str == null || str.length() < 1) {
return "";
}
String[] split = str.split(" ");
StringBuffer stringBuffer = new StringBuffer();
for (String s : split) {
stringBuffer.append(s);
stringBuffer.append(tagStr);
}
CharSequence charSequence = stringBuffer.subSequence(0, stringBuffer.length() - tagStr.length());
return charSequence.toString();
}
複製代碼
replace
方法,若是僅僅來說替換字符串的話,是最好的方法,關鍵的方法是indexOf(this, targetStr, lastMatch)
.StringBuffer sb = new StringBuffer();
sb.append(str);
// todo 最節能的方法
sb.toString().replace(" ", "%20");
複製代碼
StringBuffer
,經過插入最大角標的地方,不斷的插入,就能夠了private String replaceSpaces(String string) {
//判斷是否 輸入合法
if (string == null || string.length() < 1) {
return "";
}
char[] chars = string.toCharArray();
// 統計有多少的空白的數組
int whiteCount = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == ' ') {
whiteCount++;
}
}
if (whiteCount == 0) {
return string;
}
//最本來的長度
int indexold = string.length() - 1;
// 轉換完成後的長度
int newlength = string.length() + whiteCount * 2;
//新的長度
int indexnew = newlength - 1;
StringBuffer stringBuffer = new StringBuffer(string);
//設置新的buffer的長度
stringBuffer.setLength(newlength);
for (; indexold >= 0 && indexold < newlength; indexold--) {
// 原來的 字符串的最後一位爲空格
if (string.charAt(indexold) == ' ') {
stringBuffer.setCharAt(indexnew--, '0');
stringBuffer.setCharAt(indexnew--, '2');
stringBuffer.setCharAt(indexnew--, '%');
} else {//不爲空的話,就直接放進去 就好了
stringBuffer.setCharAt(indexnew--, string.charAt(indexold));
}
}
return stringBuffer.toString();
}
複製代碼
public static class ListNode {
int val;
ListNode next;
public ListNode(int v){
this.val=v;
}
}
複製代碼
ListNode listNode = new ListNode(10);
ListNode listNode1 = new ListNode(11);
ListNode listNode2 = new ListNode(12);
ListNode listNode3 = new ListNode(13);
ListNode listNode4 = new ListNode(14);
listNode.next=listNode1;
listNode1.next=listNode2;
listNode2.next=listNode3;
listNode3.next=listNode4;
複製代碼
public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
arrayList.clear();
if (listNode != null) {
printListFromTailToHead(listNode.next);//指向下一個節點
arrayList.add(listNode.val);//將當前節點的值存到列表中
}
return arrayList;
}
複製代碼
Stack
的特色,Stack
類:繼承自Vector
,實現一個後進先出的棧,不太明白的同窗能夠看這裏經常使用集合的原理分析;private static void doWhat(ListNode listNode) {
Stack<ListNode> stack = new Stack<>();
while (listNode!=null){
stack.push(listNode);
listNode=listNode.next;
}
System.out.println(" stack "+stack.size());
// for (int i=0;i<stack.size();i++){
// System.out.println("每一個該打印的元素 ::"+stack.get(i).val);
// }
ListNode tmp;
while (!stack.empty()){
// 移除堆棧頂部的對象,並做爲此函數的值返回該對象。
tmp = stack.pop();
System.out.println("tmp="+tmp.val);
// System.out.println("每一個該打印的元素 :"+tmp.val);
}
}
複製代碼
(left subtree)
和「右子樹」(right subtree)
。二叉樹常被用於實現二叉查找樹和二叉堆。樹的數據結構可以同時具有數組查找快的優勢以及鏈表插入和刪除快的優勢public interface Tree {
//查找節點
Node find(int key);
//插入新節點
boolean insert(int data);
//中序遍歷
void infixOrder(Node current);
//前序遍歷
void preOrder(Node current);
//後序遍歷
void postOrder(Node current);
//查找最大值
Node findMax();
//查找最小值
Node findMin();
//刪除節點
boolean delete(int key);
}
複製代碼
public class Node {
int data; //節點數據
Node leftChild; //左子節點的引用
Node rightChild; //右子節點的引用
public Node(int data){
this.data = data;
}
//打印節點內容
public void display(){
System.out.println(data);
}
@Override
public String toString() {
return super.toString();
}
}
複製代碼
BinaryTree bt = new BinaryTree();
// 第一個插入的結點是 根節點
bt.insert(50);
bt.insert(20);
bt.insert(80);
bt.insert(10);
bt.insert(30);
bt.insert(60);
bt.insert(90);
bt.insert(25);
bt.insert(85);
bt.insert(100);
複製代碼
//插入節點
public boolean insert(int data) {
Node newNode = new Node(data);
if (root == null) {//當前樹爲空樹,沒有任何節點
root = newNode;
return true;
} else {
Node current = root;
Node parentNode = null;
while (current != null) {
parentNode = current;
if (current.data > newNode.data) {//當前值比插入值大,搜索左子節點
current = current.leftChild;
if (current == null) {//左子節點爲空,直接將新值插入到該節點
parentNode.leftChild = newNode;
return true;
}
} else {
current = current.rightChild;
if (current == null) {//右子節點爲空,直接將新值插入到該節點
parentNode.rightChild = newNode;
return true;
}
}
}
}
return false;
}
複製代碼
public void preOrder(Node current) {
if (current != null) {
System.out.print(current.data + " ");
infixOrder(current.leftChild);
infixOrder(current.rightChild);
}
}
複製代碼
public void infixOrder(Node current) {
if (current != null) {
infixOrder(current.leftChild);
System.out.print(current.data + " ");
infixOrder(current.rightChild);
}
}
複製代碼
//找到最大值
public Node findMax() {
Node current = root;
Node maxNode = current;
while (current != null) {
maxNode = current;
current = current.rightChild;
}
return maxNode;
}
//找到最小值
public Node findMin() {
Node current = root;
Node minNode = current;
while (current != null) {
minNode = current;
current = current.leftChild;
}
return minNode;
}
複製代碼
{50 10 20 25 30 60 80 85 90 100}
和中序遍歷序列{10 20 25 30 50 60 80 85 90 100}
, 重建二叉樹並輸出它的頭結點。09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node50 是那邊啊 根
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node20 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node10 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node30 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node25 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node80 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node60 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node90 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node85 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node100 是那邊啊 右
複製代碼
public static Node reConstructBinaryTree(int[] pre, int[] in) {
if (pre == null || in == null || pre.length != in.length)//若是先序或者中序數組有一個爲空的話,就沒法建樹,返回爲空
return null;
else {
return reBulidTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
}
/**
* @param pre
* @param startPre
* @param endPre
* @param in
* @param startIn
* @param endIn
* @return
*/
private static Node reBulidTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
if (startPre > endPre || startIn > endIn)//先對傳的參數進行檢查判斷
return null;
int root = pre[startPre];//數組的開始位置的元素是跟元素
int locateRoot = locate(root, in, startIn, endIn);//獲得根節點在中序數組中的位置 左子樹的中序和右子樹的中序以根節點位置爲界
if (locateRoot == -1) //在中序數組中沒有找到跟節點,則返回空
return null;
Node treeRoot = new Node(root);//建立樹根節點
treeRoot.leftChild = reBulidTree(pre, startPre + 1, startPre + locateRoot - startIn, in, startIn, locateRoot - 1);//遞歸構建左子樹
treeRoot.rightChild = reBulidTree(pre, startPre + locateRoot - startIn + 1, endPre, in, locateRoot + 1, endIn);//遞歸構建右子樹
return treeRoot;
}
//找到根節點在中序數組中的位置,根節點以前的是左子樹的中序數組,根節點以後的是右子樹的中序數組
private static int locate(int root, int[] in, int startIn, int endIn) {
for (int i = startIn; i < endIn; i++) {
if (root == in[i])
return i;
}
return -1;
}
複製代碼
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 新新----的中序遍歷的開始
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node50 是那邊啊 根
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node10 是那邊啊 左
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node20 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node25 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node60 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node80 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node85 是那邊啊 右
09-02 05:51:53.177 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node90 是那邊啊 右
09-02 05:51:53.185 2590-2590/com.android.interview I/System.out: 新新----的中序遍歷的結束
複製代碼
public static Node reConstructBinaryTreeNew(int[] pre, int[] in) {
if (pre.length == 0 || in.length == 0)
return null;
Node node = new Node(pre[0]);
for (int i = 0; i < pre.length; i++) {
if (pre[0] == in[i]) {
node.leftChild = reConstructBinaryTreeNew(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
node.rightChild = reConstructBinaryTreeNew(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
break;
}
}
return node;
}
複製代碼
09-02 05:51:53.185 2590-2590/com.android.interview I/System.out: 新新----的中序遍歷的開始------------
09-02 05:51:53.185 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node50 是那邊啊 根
09-02 05:51:53.185 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node10 是那邊啊 左
09-02 05:51:53.186 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node20 是那邊啊 右
09-02 05:51:53.194 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node25 是那邊啊 右
09-02 05:51:53.211 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node30 是那邊啊 右
09-02 05:51:53.212 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node60 是那邊啊 右
09-02 05:51:53.212 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node80 是那邊啊 右
09-02 05:51:53.212 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node85 是那邊啊 右
09-02 05:51:53.213 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node90 是那邊啊 右
09-02 05:51:53.213 2590-2590/com.android.interview I/System.out: 這個值是什麼啊 Node100 是那邊啊 右
09-02 05:51:53.214 2590-2590/com.android.interview I/System.out: 新新----的中序遍歷的結束------------
複製代碼
public class Test {
/**
* 請實現一個函數,把字符串中的每一個空格替換成"%20",例如「We are happy.「,則輸出」We%20are%20happy.「。
*
* @param string 要轉換的字符數組
* @param usedLength 已經字符數組中已經使用的長度
* @return 轉換後使用的字符長度,-1表示處理失敗
*/
public static int replaceBlank(char[] string, int usedLength) {
// 判斷輸入是否合法
if (string == null || string.length < usedLength) {
return -1;
}
// 統計字符數組中的空白字符數
int whiteCount = 0;
for (int i = 0; i < usedLength; i++) {
if (string[i] == ' ') {
whiteCount++;
}
}
// 計算轉換後的字符長度是多少
int targetLength = whiteCount * 2 + usedLength;
int tmp = targetLength; // 保存長度結果用於返回
if (targetLength > string.length) { // 若是轉換後的長度大於數組的最大長度,直接返回失敗
return -1;
}
// 若是沒有空白字符就不用處理
if (whiteCount == 0) {
return usedLength;
}
usedLength--; // 從後向前,第一個開始處理的字符
targetLength--; // 處理後的字符放置的位置
// 字符中有空白字符,一直處理到全部的空白字符處理完
while (usedLength >= 0 && usedLength < targetLength) {
// 如是當前字符是空白字符,進行"%20"替換
if (string[usedLength] == ' ') {
string[targetLength--] = '0';
string[targetLength--] = '2';
string[targetLength--] = '%';
} else { // 不然移動字符
string[targetLength--] = string[usedLength];
}
usedLength--;
}
return tmp;
}
}
複製代碼
這三種的方式的結果也是同樣的,我本身認爲二叉樹沒有重構成功,若是有大佬明白的,能夠指點下,謝謝了!android
謝謝如下資料給與個人幫助git