假如二维数组为 {{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