剑指Offer——Java答案
来源:互联网 发布:网络电视剧拍摄许可证 编辑:程序博客网 时间:2024/05/18 01:43
欢迎访问 博客新址
第二章 面试需要的基础知识
数组 - 二维数组中查找
- 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
方法一
public class Solution { public boolean Find(int [][] array, int target) { for (int i=0; i<array.length; i++) { for (int j=0; j<array[i].length; j++) { if (array[i][j] == target) return true; } } return false; }}
方法二
- 时间复杂度 O(n)
public class Solution { public boolean Find(int [][] array, int target) { int row =0; int col = array[0].length-1; int numRow = array.length; while (row < numRow && col>=0) { if (array[row][col] > target) col--; else if (array[row][col] < target) row++; else { return true; // 相等,返回true } } return false; //遍历完,没有找到相等值,返回false }}
替换空格
方法一
- 借用String.replace()
public class Solution { public String replaceSpace(StringBuffer str) { String str1 = new String(str); return str1.replace(" ", "%20"); }}
方法二
- 使用字符数组实现
public class Solution { public String replaceSpace(StringBuffer str) { String str1 = new String(str); char[] charArr = str1.toCharArray(); // 计算源字符串的长度和空格的数量 int originalLength = charArr.length; int numberOfBlank = 0; for (char item : charArr) if (item == ' ') numberOfBlank++; // 计算新的字符串长度 int newLength = originalLength + numberOfBlank*2; char[] newcharArr = new char[newLength]; // int indexOfOriginal = originalLength-1; int indexOfNew = newLength-1; while(indexOfOriginal>=0) { if (charArr[indexOfOriginal] == ' ') { newcharArr[indexOfNew--] = '0'; newcharArr[indexOfNew--] = '2'; newcharArr[indexOfNew--] = '%'; indexOfOriginal--; } else { newcharArr[indexOfNew--] = charArr[indexOfOriginal--]; } } return String.valueOf(newcharArr); }}
从头到尾打印链表
import java.util.ArrayList;class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ArrayList<Integer> printListFromTailToHead(ListNode listNode) { ArrayList<Integer> al = new ArrayList<Integer>(); if (listNode == null) { return al; } ListNode p = listNode; while (p != null) { al.add(p.val); p = p.next; } int lower = 0; int higher =al.size()-1; while (lower < higher) { int temp = al.get(lower); al.set(lower, al.get(higher)); al.set(higher, temp); lower++; higher--; } return al; }}
重建二叉树
import java.util.Arrays;class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; }}public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] in) { if (pre==null || in==null) // 判空 return null; //生成根节点 int rootValue = pre[0]; TreeNode root = new TreeNode(rootValue); root.left = root.right = null; // 一个节点的情况 if (pre.length==1) { if (in.length==1 && pre[0]==in[0]) return root; else System.out.println("Invalid input."); } // 在中序遍历中查找根节点的值 int rootInorder =0; while (rootInorder<in.length && in[rootInorder]!=rootValue) rootInorder++; // 构建左子树 int[] leftPre = Arrays.copyOfRange(pre, 1, rootInorder+1); int[] leftIn = Arrays.copyOfRange(in, 0, rootInorder); if (leftPre.length>0) { root.left = reConstructBinaryTree(leftPre, leftIn); } // 构建右子树 int[] rightPre = Arrays.copyOfRange(pre, rootInorder+1, pre.length); int[] rightIn = Arrays.copyOfRange(in, rootInorder+1, in.length); if (rightPre.length>0) { root.right = reConstructBinaryTree(rightPre, rightIn); } return root; }}
用两个栈实现队列
import java.util.Stack;public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); } public int pop() { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } if (stack2.isEmpty()) { Exception e = new Exception("123"); try { throw e; } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } return stack2.pop(); }}
旋转数组的最小值
import java.util.ArrayList;public class Solution { public int minNumberInRotateArray(int [] array) { if (array.length == 0) return 0; int index1 = 0; int index2 = array.length-1; int indexMid = index1; while (array[index1] >= array[index2]) { if (index2-index1==1) { indexMid = index2; break; } indexMid = (index1+index2)/2; if(array[indexMid] >= array[index1]) index1 = indexMid; else if (array[indexMid] <= array[index2]) index2 = indexMid; } return array[indexMid]; }}
斐波那契数列
public class Solution { public int Fibonacci(int n) { if (n<=0) return 0; if (n==1) return 1; int fibOne=1; int fibTwo=0; while (n > 1) { fibOne = fibOne + fibTwo; fibTwo = fibOne - fibTwo; n--; } return fibOne; }}
跳台阶
- 类似斐波那契数列
public class Solution { public int JumpFloor(int target) { if (target <= 2) return target; int resOne = 2; int resTwo = 1; while (target>2) { resOne = resOne + resTwo; resTwo = resOne - resTwo; target--; } return resOne; }}
变态跳台阶
- 等比数列
f(n) = 2^(n-1)
public class Solution { public int JumpFloorII(int target) { if (target < 1) return 0; if (target == 1) return 1; int result=1; while (target > 1) { result *= 2; target--; } return result; }}
矩形覆盖
- 斐波那契数列
public class Solution { public int RectCover(int target) { if (target<=0) return 0; if (target<=2) return target; int resOne = 2; int resTwo = 1; while (target > 2) { resOne = resOne + resTwo; resTwo = resOne - resTwo; target--; } return resOne; }}
二进制中1的个数
- 因为Java中没有无符号整数,因此限定循环的次数。
public class Solution { public int NumberOf1(int n) { int flag = 1; int num = 0; for (int i=0; i<32; i++) { if ((flag & n) != 0) { num++; } flag <<= 1; } return num; }}
第三章 高质量的代码
数值的整数次方
public class Solution { public double Power(double base, int exponent) { if (exponent == 0) return 1; int exp=0; double result=1; if (exponent > 0) exp = exponent; else exp = -exponent; while (exp > 0) { result *= base; exp--; } if (exponent < 0) result = 1/result; return result; }}
调整数组顺序使奇数位于偶数前面
import java.util.ArrayList;public class Solution { public void reOrderArray(int [] array) { if (array!=null && array.length>1) { ArrayList<Integer> alOdd = new ArrayList<>(); ArrayList<Integer> alEven = new ArrayList<>(); for (int elem : array) { if (elem % 2 == 1) alOdd.add(elem); else alEven.add(elem); } int ind = 0; for (int i=0; i<alOdd.size(); i++) { array[ind] = alOdd.get(i); ind++; } for (int i=0; i<alEven.size(); i++) { array[ind] = alEven.get(i); ind++; } } }}
链表中倒数第k个结点
public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if (head == null) { return head; } if (k==0) { return new ListNode(0).next; } ListNode pAhead = head; ListNode pBehind = null; for (int i=0; i<k-1; i++) { if (pAhead.next != null) pAhead = pAhead.next; else return pAhead.next; //k大于列表长度 } pBehind = head; while (pAhead.next != null) { pAhead = pAhead.next; pBehind = pBehind.next; } return pBehind; }}
翻转链表
public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ListNode ReverseList(ListNode head) { ListNode pReversedHead = null; ListNode pNode = head; ListNode pPrev = null; while (pNode != null) { ListNode pNext = pNode.next; if (pNext == null) pReversedHead = pNode; pNode.next = pPrev; pPrev = pNode; pNode = pNext; } return pReversedHead; }}
合并两个排序的链表
public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ListNode Merge(ListNode list1,ListNode list2) { if (list1 == null) { return list2; } else if (list2 == null) { return list1; } ListNode listMergeHead = null; if (list1.val < list2.val) { listMergeHead = list1; listMergeHead.next = Merge(list1.next, list2); } else { listMergeHead = list2; listMergeHead.next = Merge(list1, list2.next); } return listMergeHead; }}
树的子结构
class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { public boolean HasSubtree(TreeNode root1,TreeNode root2) { boolean result = false; if (root1!=null && root2!=null) { if (root1.val == root2.val) result = DoesTree1HaveTree2(root1, root2); if (!result) result = HasSubtree(root1.left, root2); if(!result) result = HasSubtree(root1.right, root2); } return result; } public boolean DoesTree1HaveTree2(TreeNode pRoot1, TreeNode pRoot2) { if (pRoot2 == null) // Tree2 为空 return true; if (pRoot1 == null) // Tree2非空,Tree1为空 return false; if (pRoot1.val != pRoot2.val) // Tree1 & Tree2非空 return false; return DoesTree1HaveTree2(pRoot1.left, pRoot2.left) && DoesTree1HaveTree2(pRoot1.right, pRoot2.right); }}
第四章 解决面试的思路
二叉树的镜像
class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}// 先序遍历,交换每个节点的左右节点public class Solution { public void Mirror(TreeNode root) { if (root == null) return; if (root.left==null && root.right==null) return; // 交换当前节点的左右子节点 TreeNode temp = root.left; root.left = root.right; root.right = temp; // 遍历左子节点 if (root.left != null) Mirror(root.left); // 遍历右子节点 if (root.right != null) Mirror(root.right); }}
顺时针打印矩阵
import java.util.ArrayList;public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { if (matrix == null || matrix.length<=0 || matrix[0].length<=0) return new ArrayList<Integer>(); ArrayList<Integer> result = new ArrayList<Integer>(); int start = 0; int numRow = matrix.length; int numCol = matrix[0].length; while (numRow>2*start && numCol>2*start) { PrintMatrixInCircle(matrix, numRow, numCol, start, result); start++; } return result; } public void PrintMatrixInCircle(int[][] matrix, int numRow, int numCol, int start, ArrayList<Integer> result) { int endX = numCol-1-start; int endY = numRow-1-start; // 从左到右打印一行 for (int i=start; i<=endX; ++i) { result.add(matrix[start][i]); } // 从上到下打印一行 if (start < endY) { for (int i=start+1; i<=endY; i++) { result.add(matrix[i][endX]); } } // 从右到左打印一行 if (start<endX && start<endY) { for (int i=endX-1; i>=start; i--) { result.add(matrix[endY][i]); } } // 从下到上打印一行 if (start<endX && start<endY-1) { for(int i=endY-1; i>=start+1; i--) { result.add(matrix[i][start]); } } }}
包含min函数的栈
import java.util.Stack;public class Solution { Stack<Integer> dataStack = new Stack<Integer>(); Stack<Integer> minStack = new Stack<Integer>(); public void push(int node) { dataStack.push(node); if (minStack.isEmpty() || node < minStack.peek()) minStack.push(node); else minStack.push(minStack.peek()); } public void pop() { assert(!dataStack.isEmpty() && !minStack.isEmpty()); dataStack.pop(); minStack.pop(); } public int top() { assert(!dataStack.isEmpty() && !minStack.isEmpty()); return dataStack.peek(); } public int min() { assert(!dataStack.isEmpty() && !minStack.isEmpty()); return minStack.peek(); }}
栈的压入、弹出序列
import java.util.Stack;public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { boolean bPossible = false; // 判空 if (pushA==null || popA==null) return bPossible; if (pushA.length != popA.length) return bPossible; int nLength = pushA.length; int nextPushInd = 0; int nextPopInd = 0; Stack<Integer> stack = new Stack<Integer>(); while (nextPopInd < nLength) { while (stack.empty() || stack.peek() != popA[nextPopInd]) { if (nextPushInd == nLength) break; stack.push(pushA[nextPushInd]); nextPushInd++; } if (stack.peek() != popA[nextPopInd]) break; stack.pop(); nextPopInd++; } if (stack.empty() && nextPopInd== nLength) bPossible=true; System.out.println(nextPushInd); System.out.println(nextPopInd); return bPossible; } public static void main(String[] args) { int[] pushA = {1,2,3,4,5}; int[] popA = {4,5,3,2,1}; Solution solution = new Solution(); boolean result = solution.IsPopOrder(pushA, popA); System.out.println(result); }}
从上往下打印二叉树
- 使用队列实现
import java.util.ArrayList;import java.util.LinkedList;import java.util.Queue;class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { if (root==null) return new ArrayList<Integer>(); ArrayList<Integer> result = new ArrayList<Integer>(); Queue<TreeNode> queue = new LinkedList<TreeNode>(); //创建队列 queue.add(root); while (queue.size() > 0) { TreeNode temp = queue.peek(); queue.remove(); result.add(temp.val); if (temp.left != null) queue.add(temp.left); if (temp.right != null) queue.add(temp.right); } return result; }}
二叉搜索树的后序遍历序列
- 二叉搜索树的左子树结点小于根节点,右子树结点大于根结点;
- 根结点位于后续遍历序列的最后位置
import java.util.Arrays;public class Solution { public boolean VerifySquenceOfBST(int [] sequence) { if (sequence == null || sequence.length==0) return false; int root = sequence[sequence.length-1]; //根存储在数组的最后位置 // 二叉搜索树中左子树的结点小于根节点 int i=0; for (; i<sequence.length-1; i++) { if (sequence[i] > root) break; } // 二叉搜索树中右子树的结点大于根节点 int j = i; for (; j<sequence.length-1; j++) { if (sequence[j] < root) { return false; } } // 判断左子树是不是二叉搜索树 boolean left = true; if (i > 0) { left = VerifySquenceOfBST(Arrays.copyOfRange(sequence, 0, i)); } // 判断右子树是不是二叉搜索树 boolean right = true; if (i < sequence.length-1) right = VerifySquenceOfBST(Arrays.copyOfRange(sequence, i, sequence.length-1)); return (left && right); }}
二叉树中和为某一值的路径
import java.util.ArrayList;import java.util.Iterator;class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) { if (root == null) return new ArrayList<ArrayList<Integer>>(); ArrayList<ArrayList<Integer>> arrayList = new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> path = new ArrayList<Integer>(); // 栈,用做存储路径 int currentSum = 0; FindPath(root, target, arrayList, path, currentSum); return arrayList; } public void FindPath(TreeNode root,int target, ArrayList<ArrayList<Integer>> arrayList, ArrayList<Integer> path, int currentSum) { currentSum += root.val; path.add(root.val); // 如果是叶结点,并且路径和符合条件 boolean isLeaf = ((root.left==null) && (root.right==null)); if (currentSum==target && isLeaf) { Iterator<Integer> iterator = path.iterator(); ArrayList<Integer> pathTemp = new ArrayList<>(); while (iterator.hasNext()) { pathTemp.add(iterator.next()); } arrayList.add(pathTemp); } //如果不是叶结点,遍历它的子节点 if (root.left != null) FindPath(root.left, target, arrayList, path, currentSum); if (root.right != null) FindPath(root.right, target, arrayList, path, currentSum); // 返回父节点前,在路径上删除当前节点 path.remove(path.size()-1); }}
复杂链表的复制
- 分成3步实现
class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; }}public class Solution { public RandomListNode Clone(RandomListNode pHead) { CloneNode(pHead); ConnectRandomNodes(pHead); return ReconnectNodes(pHead); } // 第一步:创建N的结点,并链接到原结点的后面 public void CloneNode(RandomListNode pHead) { RandomListNode pNode = pHead; while (pNode != null) { RandomListNode pCloned = new RandomListNode(pNode.label); pCloned.next = pNode.next; pCloned.random = null; // 冗余 pNode.next = pCloned; pNode = pCloned.next; } } // 第二部:设置复制出来的节点的random public void ConnectRandomNodes (RandomListNode pHead) { RandomListNode pNode = pHead; while (pNode != null) { RandomListNode pCloned = pNode.next; if (pNode.random != null) { // 存在随机链接 pCloned.random = pNode.random.next; } pNode = pCloned.next; } } // 第三步:将链表分解成两部分:原链表和复制的链表 public RandomListNode ReconnectNodes (RandomListNode pHead) { RandomListNode pNode = pHead; RandomListNode pClonedHead = null; RandomListNode pClonedNode = null; //处理头结点 if (pNode != null) { pClonedHead = pClonedNode = pNode.next; pNode.next = pClonedNode.next; pNode = pNode.next; } //处理后面的结点 while (pNode != null) { pClonedNode.next = pNode.next; pClonedNode = pClonedNode.next; pNode.next = pClonedNode.next; pNode = pNode.next; } return pClonedHead; }}
二叉搜索树与双向链表
- 这道题有点难
class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { public TreeNode Convert(TreeNode pRootOfTree) { if (pRootOfTree == null) return pRootOfTree; //TreeNode pLastOfList = null; TreeNode pLastOfList = new TreeNode(0); pLastOfList = ConvertNode(pRootOfTree, pLastOfList); TreeNode pHeadOfList = pLastOfList; while (pLastOfList!=null && pHeadOfList.left!=null) { pHeadOfList = pHeadOfList.left; } pHeadOfList = pHeadOfList.right; pHeadOfList.left = null; return pHeadOfList; } public TreeNode ConvertNode (TreeNode pNode, TreeNode pLastOfList) { if (pNode == null) return pNode; TreeNode pCurrent = pNode; if (pCurrent.left != null) pLastOfList = ConvertNode(pCurrent.left, pLastOfList); pCurrent.left = pLastOfList; if (pLastOfList != null) pLastOfList.right = pCurrent; pLastOfList = pCurrent; if (pCurrent.right != null) { pLastOfList = ConvertNode(pCurrent.right, pLastOfList); } return pLastOfList; } public static void main(String[] args) { TreeNode a = new TreeNode(10); TreeNode b = new TreeNode(6); TreeNode c = new TreeNode(14); TreeNode d = new TreeNode(4); TreeNode e = new TreeNode(8); TreeNode f = new TreeNode(12); TreeNode g = new TreeNode(16); a.left = b; a.right = c; b.left = d; b.right = e; c.left = f; c.right = g; Solution solution = new Solution(); TreeNode pHead = solution.Convert(a); while (pHead != null) { System.out.print(pHead.val + "→"); pHead = pHead.right; } System.out.println(); while (pHead != null) { System.out.print(pHead.val + "→"); pHead = pHead.left; } }}
字符串的排列
import java.util.ArrayList;import java.util.Arrays;public class Solution { public ArrayList<String> Permutation(String str) { if (str == null) return null; //return new ArrayList<String>(); ArrayList<String> arrayList = new ArrayList<String>(); StringBuffer stringBuffer = new StringBuffer(str); Permutation(arrayList, stringBuffer, 0); String[] strArray = new String[arrayList.size()]; arrayList.toArray(strArray); Arrays.sort(strArray); for (int i=0; i<arrayList.size(); i++) { arrayList.set(i, strArray[i]); } return arrayList; } public void Permutation(ArrayList<String> arrayList, StringBuffer stringBuffer, int ind) { if (ind == stringBuffer.length()-1) { if (!arrayList.contains(stringBuffer.toString())) { arrayList.add(stringBuffer.toString()); } } else { for (int i=ind; i<stringBuffer.length(); i++) { char temp = stringBuffer.charAt(i); stringBuffer.setCharAt(i, stringBuffer.charAt(ind)); stringBuffer.setCharAt(ind, temp); Permutation(arrayList, stringBuffer, ind+1); temp = stringBuffer.charAt(i); stringBuffer.setCharAt(i, stringBuffer.charAt(ind)); stringBuffer.setCharAt(ind, temp); } } } public static void main (String[] args) { Solution solution = new Solution(); ArrayList<String> arrayList = new ArrayList<String>(); arrayList = solution.Permutation("abc"); System.out.println(arrayList.size()); for (String item : arrayList) { System.out.println(item); } }}
第五章 优化时间和空间效率
数组中出现次数超过一半的数字
// 中位数,快速排序,partitionpublic class Solution { public int MoreThanHalfNum_Solution(int [] array) { if (CheckInvalidArray(array)) // 检查输入是否有效 return 0; int result = array[0]; int times = 1; for (int i=1; i<array.length; i++) { if (times==0) { result = array[i]; times = 1; } else if (array[i] == result) times++; else times--; } if (!CheckMoreThanHalf(array, result)) return 0; return result; } public boolean CheckInvalidArray (int[] array) { boolean g_bInputInvalid = false; if (array==null || array.length<=0) { g_bInputInvalid = true; } return g_bInputInvalid; } boolean CheckMoreThanHalf (int[] array, int number) { int times = 0; for (int i=0; i<array.length; i++) { if (array[i] == number) times++; } boolean isMoreThanHalf = true; if (times * 2 <= array.length) { isMoreThanHalf = false; } return isMoreThanHalf; }}
最小的K个数
import java.util.ArrayList;public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { int n = input.length; if (input==null || n<=0 || k<=0 || k>n) return new ArrayList<Integer>(); int start = 0; int end = n-1; int index = Partition(input, start, end); while (index != k-1) { if (index>k-1) { end = index-1; index = Partition(input, start, end); } else { start = index+1; index = Partition(input, start, end); } } ArrayList<Integer> result = new ArrayList<Integer>(); for (int i=0; i<k; i++) { result.add(input[i]); } return result; } public int Partition(int[] data, int start, int end) { int length = data.length; if (data==null || length<=0 || start<0 || end>=length) try { throw new Exception("Invalid Parameters"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } int index = (int)(Math.random()*(end-start) + start); Swap(data, index, end); int small = start-1; for (index=start; index<end; index++) { if (data[index] < data[end]) { small++; if (small != index) Swap(data, index, small); } } small++; Swap(data, small, end); return small; } public void Swap (int[] data, int index, int end) { int temp = data[index]; data[index] = data[end]; data[end] = temp; }}
连续子数组的最大和
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if (array==null || array.length<=0) return 0; int nCurSum = 0; int nGreatestSum = Integer.MIN_VALUE; for (int i=0; i<array.length; i++) { if (nCurSum<0) nCurSum = array[i]; else nCurSum += array[i]; if (nCurSum>nGreatestSum) nGreatestSum = nCurSum; } return nGreatestSum; }}
整数中1出现的次数(从1到n整数中1出现的次数)
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int number = 0; for (int i=1; i<=n; i++) number += NumberOf1(i); return number; } public int NumberOf1(int n) { int number = 0; while (n > 0) { if (n%10 == 1) number++; n /= 10; } return number; } public static void main (String[] args) { Solution solution = new Solution(); System.out.println(solution.NumberOf1Between1AndN_Solution(11)); }}
把数组排成最小的数
- 确定一种排序规则
- 隐性的大数问题
import java.util.Arrays;import java.util.Comparator;public class Solution { public String PrintMinNumber(int [] numbers) { if (numbers==null || numbers.length<=0) return new String(); // 数组转化成字符串数组 String[] strArray = new String[numbers.length]; for (int i=0; i<numbers.length; i++) strArray[i] = String.valueOf(numbers[i]); //排序 Arrays.sort(strArray, new ComparatorTest()); // 连接 StringBuilder sBuilder = new StringBuilder(); for (int i=0; i<numbers.length; i++) { sBuilder.append(strArray[i]); } return sBuilder.toString(); } public static void main(String[] args) { Solution solu = new Solution(); int[] a = {3, 5, 1, 4,2}; String str = new String(); str = solu.PrintMinNumber(a); System.out.println(str); }}class ComparatorTest implements Comparator<String> { @Override public int compare(String str1, String str2) { String strCombine1 = str1 + str2; String strCombine2 = str2 + str1; return strCombine1.compareTo(strCombine2); }}
丑数
- 第一种方法,复杂度过高
public class Solution { public int GetUglyNumber_Solution(int index) { if (index <= 0) return 0; int number = 0; int uglyFound = 0; while (uglyFound < index) { number++; if (IsUgly(number)) uglyFound++; } return number; } public boolean IsUgly (int number) { while (number%2 == 0) number /=2; while (number%3 == 0) number /=3; while (number%5 == 0) number /=5; return (number==1) ? true : false; } public static void main(String[] args) { Solution solu = new Solution(); System.out.println(solu.GetUglyNumber_Solution(1000)); }}
- 第二种方法:优化时间复杂度
public class Solution { public int GetUglyNumber_Solution(int index) { if (index <= 0) return 0; int[] uglyNumbers = new int[index]; uglyNumbers[0] = 1; int nextUglyIndex = 1; int ind2 = 0; int ind3 = 0; int ind5 = 0; while (nextUglyIndex < index) { int min = Min(uglyNumbers[ind2]*2, uglyNumbers[ind3]*3, uglyNumbers[ind5]*5); uglyNumbers[nextUglyIndex] = min; while(uglyNumbers[ind2]*2 <= uglyNumbers[nextUglyIndex]) ind2++; while(uglyNumbers[ind3]*3 <= uglyNumbers[nextUglyIndex]) ind3++; while(uglyNumbers[ind5]*5 <= uglyNumbers[nextUglyIndex]) ind5++; ++nextUglyIndex; } int ugly = uglyNumbers[nextUglyIndex-1]; return ugly; } int Min(int number1, int number2, int number3) { int min = (number1<number2) ? number1 : number2; min = (min<number3) ? min : number3; return min; } public static void main(String[] args) { Solution solu = new Solution(); System.out.println(solu.GetUglyNumber_Solution(5)); }}
第一个只出现一次的字符位置
public class Solution { public int FirstNotRepeatingChar(String str) { if (str==null || str.length()<=0) { return -1; } int tableSize = 256; int[] hashTable = new int[tableSize]; //自动初始化为0 for (int i=0; i<str.length(); i++) hashTable[str.charAt(i)]++; for (int i=0; i<str.length(); i++) { if (hashTable[str.charAt(i)]==1) { return i; } } return -1; } public static void main(String[] args) { Solution solu = new Solution(); String str = "google"; System.out.println(solu.FirstNotRepeatingChar(str)); }}
—数组中的逆序对—
- 错误
public class Solution { public int InversePairs(int [] array) { if (array==null || array.length<=0) return 0; int[] copy = new int[array.length]; for (int i=0; i<array.length; ++i) copy[i] = array[i]; long count=InversePairsCore(array, copy, 0, array.length-1); return (int)count; } public long InversePairsCore(int[] array, int[] copy, int start, int end) { if (start == end) { copy[start] = array[start]; return 0; } int length = (end-start)/2; long left = InversePairsCore(copy, array, start, start+length); long right = InversePairsCore(copy, array, start+length+1, end); // i初始化为前半段最后一个数字的下标 int i= start + length; // j初始化为后半段最后一个数字的下标 int j = end; int indexCopy = end; long count = 0; while (i>=start && j>=start+length+1) { if (array[i] > array[j]) { copy[indexCopy--] = array[i--]; count += j-start-length; } else { copy[indexCopy--] = array[j--]; } } for (; i>=start; --i) copy[indexCopy--] = array[i]; for (; j>=start+length+1; --j) copy[indexCopy--] = array[j]; return left+right+count; } public static void main(String[] args) { Solution solu = new Solution(); int[] a = {364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575}; System.out.println(solu.InversePairs(a)); }}
两个链表的第一个公共节点
- 先计算链表的长度,然后让长链表先走几步,再让两个链表同时走,第一个相同的结点就是结果。
- 两个链表的形状是Y形。
class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { if (pHead1==null) return pHead1; else if(pHead2==null) return pHead2; int nLength1 = GetListLength(pHead1); int nLength2 = GetListLength(pHead2); int nLengthDif = nLength1 - nLength2; ListNode pListHeadLong = pHead1; ListNode pListHeadShort = pHead2; if (nLength2 > nLength1) { pListHeadLong = pHead2; pListHeadShort = pHead1; nLengthDif = nLength2-nLength1; } // 长链表先走几步 for (int i=0; i<nLengthDif; i++) pListHeadLong = pListHeadLong.next; // 再同时在两个链表上遍历 while((pListHeadLong!=null) && (pListHeadShort!=null) && (pListHeadLong!=pListHeadShort)) { pListHeadLong = pListHeadLong.next; pListHeadShort = pListHeadShort.next; } // 得到第一个公共结点 ListNode pFirstCommonNode = pListHeadLong; return pFirstCommonNode; } // 计算链表的长度 public int GetListLength(ListNode head) { int nLength = 0; ListNode node = head; while (node != null) { nLength++; node = node.next; } return nLength; }}
第六章 面试中的各项能力
数字在排序数组中出现的次数
- 通过二分查找找到第一个k和最后一个k的位置,即可。
public class Solution { public int GetNumberOfK(int [] array , int k) { if (array==null || array.length<=0) return 0; int number=0; int length = array.length; int first = GetFirstK(array, length, k, 0, length-1); int last = GetLastK(array, length, k, 0, length-1); if (first>-1 && last>-1) number = last-first+1; return number; } // 计算第一个K的索引位置 int GetFirstK(int[] array, int length, int k, int start, int end) { if (start>end) return -1; int middleIndex = (start+end)/2; int middleData = array[middleIndex]; if(middleData == k) { if ((middleIndex>0 && array[middleIndex-1]!=k) || middleIndex==0) return middleIndex; else end = middleIndex-1; } else if(middleData>k) end = middleIndex-1; else start = middleIndex+1; return GetFirstK(array, length, k, start, end); } // 计算最后一个k的位置 int GetLastK(int[] array, int length, int k, int start, int end) { if (start>end) return -1; int middleIndex = (start+end)/2; int middleData = array[middleIndex]; if(middleData == k) { if ((middleIndex<length-1 && array[middleIndex+1]!=k) || middleIndex==length-1) return middleIndex; else start = middleIndex+1; } else if(middleData<k) start = middleIndex+1; else end = middleIndex-1; return GetLastK(array, length, k, start, end); }}
二叉树的深度
- 根据树的遍历改写。
public class Solution { public int TreeDepth(TreeNode pRoot) { if (pRoot==null) return 0; int nLeft = TreeDepth(pRoot.left); int nRight = TreeDepth(pRoot.right); return (nLeft>nRight) ? (nLeft+1) : (nRight+1); }}
平衡二叉树
数组中只出现一次的数字
- 难
//num1,num2分别为长度为1的数组。传出参数//将num1[0],num2[0]设置为返回结果public class Solution { public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { int length = array.length; if (array==null || length<2) return; int resultExclusiveOR = 0; for (int i=0; i<length; i++) resultExclusiveOR ^= array[i]; int indexOf1 = FindFirstBitIs1(resultExclusiveOR); num1[0] = num2[0] = 0; for (int j=0; j<length; j++) { if (IsBit1(array[j], indexOf1)) num1[0] ^= array[j]; else num2[0] ^= array[j]; } } public int FindFirstBitIs1 (int num) { int indexBit = 0; while (((num&1)==0) && (indexBit<Integer.SIZE)) { num = num>>1; indexBit++; } return indexBit; } public boolean IsBit1 (int num, int indexBit) { num = num >> indexBit; return ((num & 1)!=0); } public static void main (String[] args) { Solution solu = new Solution(); int[] a = {2,4,3,6,3,2,5,5}; int[] b = new int[1]; int[] c = new int[1]; solu.FindNumsAppearOnce(a, b, c); System.out.println(b[0] + " " + c[0]); }}
和为S的连续正数序列
import java.util.ArrayList;public class Solution { public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) { ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); if (sum<3) return result; int small = 1; int big = 2; int middle = (1+sum)/2; int curSum = small + big; while (small < middle) { if (curSum == sum) addElem (result, small, big); while(curSum>sum && small<middle) { curSum -= small; small++; if (curSum==sum) addElem (result, small, big); } big++; curSum += big; } return result; } public void addElem (ArrayList<ArrayList<Integer>> array, int small, int big) { ArrayList<Integer> temp= new ArrayList<Integer>(); for (int i=small; i<=big; i++) { temp.add(i); } array.add(temp); } public static void main (String[] args) { Solution solu = new Solution(); ArrayList<ArrayList<Integer>> array; array = solu.FindContinuousSequence(15); for (int i=0; i<array.size(); i++) { for (int j=0; j<array.get(i).size(); j++) { System.out.print(array.get(i).get(j)); } System.out.println(); } }}
和为S的两个数字
import java.util.ArrayList;public class Solution { public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) { //boolean found = false; int length = array.length; ArrayList<Integer> al = new ArrayList<Integer>(); if (length<1) return al; int ahead = length-1; int behind = 0; while (ahead>behind) { long curSum = array[ahead] + array[behind]; if(curSum==sum) { al.add(array[behind]); al.add(array[ahead]); //found = true; break; } else if (curSum > sum) { ahead--; } else behind++; } return al; }}
左旋转字符串
public class Solution { public String LeftRotateString(String str,int n) { if (str != null) { int nLength = str.length(); if (nLength>0 && n>0 && n<nLength) { int begin1 = 0; int end1 = n-1; int begin2 = n; int end2 = nLength-1; char[] strArr = str.toCharArray(); Reverse(strArr, begin1, end1); Reverse(strArr, begin2, end2); Reverse(strArr, begin1, end2); str = String.copyValueOf(strArr); } } return str; } public void Reverse(char[] strArr, int begin, int end) { if (strArr==null) return; while (begin<end) { char temp = strArr[begin]; strArr[begin] = strArr[end]; strArr[end] = temp; begin++; end--; } } public static void main(String[] args) { Solution solu = new Solution(); //String str = solu.ReverseSentence("I am a student."); String str = solu.LeftRotateString("Wonderful", 2); System.out.println(str); }}
翻转单词顺序序列
public class Solution { public String ReverseSentence(String str) { if (str==null || str.length()<=0) return str; char[] strArr = str.toCharArray(); // 翻转所有的字符 Reverse(strArr, 0, strArr.length-1); // 翻转句子中每个单词 int begin = 0; int end = 0; while (begin < strArr.length-1) { if (strArr[begin] == ' ') { begin++; end++; } else if ( end == strArr.length || strArr[end]==' ') { end--; Reverse(strArr, begin, end); begin = ++end; } else { end++; } } return String.copyValueOf(strArr); } public void Reverse(char[] strArr, int begin, int end) { if (strArr==null) return; while (begin<end) { char temp = strArr[begin]; strArr[begin] = strArr[end]; strArr[end] = temp; begin++; end--; } } public static void main(String[] args) { Solution solu = new Solution(); //String str = solu.ReverseSentence("I am a student."); String str = solu.ReverseSentence("Wonderful"); System.out.println(str); }}
扑克牌顺子
import java.util.Arrays;import java.util.Comparator;public class Solution { public boolean isContinuous(int [] numbers) { int length = numbers.length; if (numbers==null || length<1) return false; Integer[] numArr = new Integer[length]; for (int i=0; i<length; i++) { numArr[i] = numbers[i]; } Arrays.sort(numArr, new ComparatorTest()); int numOfZero = 0; int numOfGap = 0; // 统计0的个数 for (int i=0; i<length;i++) if (numArr[i] == 0) numOfZero++; // 统计间隔的数目 int small = numOfZero; //第一个非零数字的位置 int big = small + 1; //第二个非零数字的位置 while (big < length) { // 如果两个数相等,不可能是顺子 if (numArr[small] == numArr[big]) return false; numOfGap += numArr[big] - numArr[small] - 1; small = big; big++; } return (numOfGap>numOfZero) ? false: true; } public static void main(String[] args) { Solution solu = new Solution(); //int a[] = {1,2,0,4,5}; int[] a = {1,3,2,6,4}; System.out.println(solu.isContinuous(a)); }}class ComparatorTest implements Comparator<Integer> { @Override public int compare(Integer num1, Integer num2) { // TODO Auto-generated method stub return num1-num2; }}
孩子们的游戏(圆圈中最后剩下的数)
- 分析规律,构建递归公式。
public class Solution { public int LastRemaining_Solution(int n, int m) { if (n<1 || m<1) return -1; int last = 0; for (int i=2; i<=n; i++) { last = (last+m)%i; } return last; }}
求1+2+3+…+n
- 要求不让使用循环,条件语句实现。
- 使用构造函数可以实现。
public class Solution { public int Sum_Solution(int n) { int sum=0; for (int i=1; i<=n; i++) { sum += i; } return sum; } public static void main (String[] args) { Solution solu = new Solution(); System.out.println(solu.Sum_Solution(10)); }}
不用加减乘除做加法
public class Solution { public int Add(int num1,int num2) { int sum, carry; do { sum = num1 ^ num2; carry = (num1 & num2) << 1; num1 = sum; num2 = carry; }while(num2 != 0); return num1; } public static void main(String[] args) { Solution solu = new Solution(); System.out.println(solu.Add(3, 34)); }}
第七章 两个面试案例
把字符串转换成整数
public class Solution { public int StrToInt(String str) { int result=0; try{ result = Integer.valueOf(str); } catch(Exception e) { //e.printStackTrace(); } return result; } public static void main (String[] args) { Solution solu = new Solution(); System.out.println(solu.StrToInt("12a")); }}
第八章 英文版新增面试题
数组中重复的数字
public class Solution { // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation; // Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++ // 这里要特别注意~返回任意重复的一个,赋值duplication[0] // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false public boolean duplicate(int numbers[],int length,int [] duplication) { duplication[0] = -1; if (numbers==null || numbers.length<1) return false; for (int i=0; i<length; i++) if (numbers[i]<0 || numbers[i]>length-1) return false; for (int i=0; i<length; i++) { while (numbers[i] != i) { if (numbers[i] == numbers[numbers[i]]) { duplication[0] = numbers[i]; return true; } // 交换第i个元素和第numbers[i]个元素 int temp = numbers[i]; numbers[i] = numbers[temp]; numbers[temp] = temp; } } return false; } public static void main (String[] args) { Solution solu = new Solution(); //int[] numbers = {2,3,1,0,2,5,3}; int[] numbers = {0,1}; int[] duplication = new int[1]; boolean b = solu.duplicate(numbers, numbers.length, duplication); System.out.println(b); System.out.println(duplication[0]); }}
构建乘积数组
public class Solution { public int[] multiply(int[] A) { int[] result = null; if (A==null || A.length<1) return result; result = new int[A.length]; // result = C*D // C result[0] = 1; for (int i=1; i<result.length; i++) { result[i] = result[i-1] * A[i-1]; } // D int temp = 1; for (int i=result.length-2; i>=0; i--) { temp *= A[i+1]; // D[i] result[i] *= temp; // result[i]=C[i]*D[i] } return result; } public static void main(String[] args) { Solution solu = new Solution(); int[] a = {1,2,3}; int[] b = new int[3]; b = solu.multiply(a); for (int i=0; i<b.length; i++) { System.out.print(b[i]); } }}
正则表达式匹配
import java.util.Arrays;public class Solution { public boolean match(char[] str, char[] pattern) { if (str==null || pattern==null) return false; return matchCore(str, pattern); } public boolean matchCore (char[] str, char[] pattern) { // 模式为空的情况 if (str.length==0 && pattern.length==0) return true; if (str.length!=0 && pattern.length==0) return false; if (pattern.length>1 && pattern[1] == '*') { //if (str[0]==pattern[0] || (pattern[0]=='.' && str.length!=0)){ if (str.length!=0 && (str[0]==pattern[0] || pattern[0]=='.')){ boolean b1, b2, b3; b1 = matchCore(Arrays.copyOfRange(str, 1, str.length), Arrays.copyOfRange(pattern, 2, pattern.length)); b2 = matchCore(Arrays.copyOfRange(str, 1, str.length), pattern); b3 = matchCore(str, Arrays.copyOfRange(pattern, 2, pattern.length)); return b1 || b2 || b3; } else { return matchCore(str, Arrays.copyOfRange(pattern, 2, pattern.length)); } } if (str.length!=0 && (str[0]==pattern[0] || pattern[0]=='.')) return matchCore(Arrays.copyOfRange(str, 1, str.length), Arrays.copyOfRange(pattern, 1, pattern.length)); return false; } public static void main (String[] args) { /* char[] str = {'b'}; char[] str2 = Arrays.copyOfRange(str, 1, str.length); System.out.println(str2.length); */ char[] str = {}; char[] pattern = {'.'}; Solution solu = new Solution(); boolean res = solu.match(str, pattern); System.out.println(res); }}
表示数值的字符串
import java.util.Arrays;public class Solution { public boolean isNumeric(char[] str) { if (str==null || str.length<1) return false; //跳过正负号 if (str.length>0 && (str[0]=='+' || str[0]=='-')) str = Arrays.copyOfRange(str, 1, str.length); if (str.length==0) return false; boolean[] isNumeric = {true}; // 跳过0-9数字 str = scanDigits(str); if (str.length>0) { // 浮点数 if (str[0] == '.') { str = Arrays.copyOfRange(str, 1, str.length); str = scanDigits(str); if (str.length>0 && (str[0]=='e' || str[0]=='E')) str = isExponential(str, isNumeric); } else if (str[0]=='e' || str[0]=='E') // 整数 str = isExponential(str, isNumeric); else isNumeric[0] = false; } return isNumeric[0] && (str.length==0); } public char[] scanDigits(char[] str) { while (str.length>0 && str[0]>='0' && str[0]<='9') { str = Arrays.copyOfRange(str, 1, str.length); //System.out.println(String.valueOf(str)); } return str; } public char[] isExponential (char[] str, boolean[] isExp) { if (str.length>0 && str[0]!='e' && str[0]!='E') { isExp[0] = false; return str; } str = Arrays.copyOfRange(str, 1, str.length); if (str.length>0 && (str[0]=='+' || str[0]=='-')) str = Arrays.copyOfRange(str, 1, str.length); if (str.length<1) { isExp[0] = false; return str; } str = scanDigits(str); isExp[0] = (str.length==0) ? true : false; return str; } public static void main (String[] args) { Solution solu = new Solution(); boolean res = solu.isNumeric("12E3".toCharArray()); System.out.println(res); }}
字符流中第一个不重复的字符
public class Solution { int[] occurrence = new int[256]; int index; public Solution() { for (int i=0; i<occurrence.length; i++) { occurrence[i] = -1; } } //Insert one char from stringstream public void Insert(char ch) { if (occurrence[ch] == -1) //没出现过,设置为索引 occurrence[ch] = index; else if (occurrence[ch]>=0) //已经出现过,标记为-2 occurrence[ch] = -2; index++; } //return the first appearence once char in current stringstream public char FirstAppearingOnce() { char ch = '#'; int minIndex = Integer.MAX_VALUE; for (int i=0; i<256; i++) { if (occurrence[i]>=0 && occurrence[i]<minIndex) { ch = (char)i; minIndex = occurrence[i]; } } return ch; }}
链表中第一个不重复的字符
public class Solution { int[] occurrence = new int[256]; int index; public Solution() { for (int i=0; i<occurrence.length; i++) { occurrence[i] = -1; } } //Insert one char from stringstream public void Insert(char ch) { if (occurrence[ch] == -1) //没出现过,设置为索引 occurrence[ch] = index; else if (occurrence[ch]>=0) //已经出现过,标记为-2 occurrence[ch] = -2; index++; } //return the first appearence once char in current stringstream public char FirstAppearingOnce() { char ch = '#'; int minIndex = Integer.MAX_VALUE; for (int i=0; i<256; i++) { if (occurrence[i]>=0 && occurrence[i]<minIndex) { ch = (char)i; minIndex = occurrence[i]; } } return ch; }}
链表中环的入口结点
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead==null) return null; // 找到环中的一个结点 ListNode meetingNode = MeetingNode(pHead); if (meetingNode==null) return null; // 计算环中节点的数目 int nodesInLoop = 1; ListNode pNode1 = meetingNode; while(pNode1.next!=meetingNode) { pNode1 = pNode1.next; nodesInLoop++; } // 移动n个 pNode1 = pHead; for (int i=0; i<nodesInLoop; i++) { pNode1 = pNode1.next; } // 同时移动pNode1和pNode2 ListNode pNode2 = pHead; while (pNode1 != pNode2) { pNode1 = pNode1.next; pNode2 = pNode2.next; } return pNode1; } public ListNode MeetingNode(ListNode pHead) { if (pHead==null) // 判空 return null; ListNode pSlow = pHead.next; // 定义慢指针 if (pSlow==null) return null; ListNode pFast = pSlow.next; while (pFast!=null && pSlow!=null) { if (pFast==pSlow) return pFast; pSlow = pSlow.next; // 慢指针走一步 pFast = pFast.next; // 快指针走两步 if (pFast!=null) pFast = pFast.next; } return null; }}
删除链表中重复的结点
class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public class Solution { public ListNode deleteDuplication(ListNode pHead) { if (pHead == null) return null; ListNode pPreNode = null; ListNode pNode = pHead; while(pNode!=null) { ListNode pNext = pNode.next; boolean needDelete = false; if (pNext!=null && pNext.val==pNode.val) needDelete = true; if (!needDelete) {//不需要删除 pPreNode = pNode; pNode = pNode.next; } else { int value = pNode.val; ListNode pToBeDel = pNode; while(pToBeDel!=null && pToBeDel.val==value) { pNext=pToBeDel.next; pToBeDel = pNext; } if (pPreNode==null) pHead = pNext; else pPreNode.next = pNext; pNode = pNext; } } return pHead; }}
二叉树的下一个结点
class TreeLinkNode { int val; TreeLinkNode left = null; TreeLinkNode right = null; TreeLinkNode next = null; TreeLinkNode(int val) { this.val = val; }}public class Solution { public TreeLinkNode GetNext(TreeLinkNode pNode) { if (pNode==null) return null; TreeLinkNode pNext = null; if (pNode.right != null) { // 查询点有右子树的情况 TreeLinkNode pRight = pNode.right; while (pRight.left != null) pRight = pRight.left; pNext = pRight; } else if (pNode.next != null) { // 查询点不存在右子树,存在父节点 TreeLinkNode pCurrent = pNode; TreeLinkNode pParent = pNode.next; while (pParent!=null && pCurrent==pParent.right) { pCurrent = pParent; pParent = pParent.next; } pNext = pParent; } return pNext; }}
对称的二叉树
class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { boolean isSymmetrical(TreeNode pRoot) { return isSymmetrical(pRoot, pRoot); } boolean isSymmetrical(TreeNode pRoot1, TreeNode pRoot2) { if (pRoot1==null && pRoot2==null) // 两个都为null return true; if (pRoot1==null || pRoot2==null) // 其中一个为null return false; if (pRoot1.val != pRoot2.val) return false; return isSymmetrical(pRoot1.left, pRoot2.right) && isSymmetrical(pRoot1.right, pRoot2.left); }}
按之字形顺序打印二叉树
import java.util.ArrayList;import java.util.Stack;class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) { if (pRoot == null) return new ArrayList<ArrayList<Integer> >(); ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); Stack<TreeNode> level0 = new Stack<TreeNode>(); Stack<TreeNode> level1 = new Stack<TreeNode>(); Stack<TreeNode> levelCurrent; Stack<TreeNode> levelNext; //Stack<TreeNode>levleOdd = new Stack<TreeNode>(); // 奇数层栈 //Stack<TreeNode>levleEven = new Stack<TreeNode>(); // 偶数层栈 int current = 0; int next = 1; level0.push(pRoot); while (!level0.empty() || !level1.empty()) { if (current == 0) { levelCurrent = level0; levelNext = level1; } else { levelCurrent = level1; levelNext = level0; } ArrayList<Integer> temp = new ArrayList<Integer>(); while (!levelCurrent.empty()) { TreeNode pNode = levelCurrent.peek(); levelCurrent.pop(); temp.add(pNode.val); if (current==0) { if (pNode.left != null) levelNext.push(pNode.left); if (pNode.right != null) levelNext.push(pNode.right); } else { if (pNode.right != null) levelNext.push(pNode.right); if (pNode.left != null) levelNext.push(pNode.left); } } result.add(temp); current = 1-current; next = 1-next; } return result; } public static void main (String[] args) { Solution solu = new Solution(); ArrayList<ArrayList<Integer> > result; TreeNode t0 = new TreeNode(8); TreeNode t1 = new TreeNode(6); TreeNode t2 = new TreeNode(10); TreeNode t3 = new TreeNode(5); TreeNode t4 = new TreeNode(7); TreeNode t5 = new TreeNode(9); TreeNode t6 = new TreeNode(11); t0.left = t1; t0.right = t2; t1.left = t3; t1.right = t4; t2.left = t5; t2.right = t6; result = solu.Print(t0); System.out.println(result.toString()); }}
把二叉树打印成多行
import java.util.ArrayList;import java.util.LinkedList;import java.util.Queue;class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}public class Solution { ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) { ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); if (pRoot == null) return result; Queue<TreeNode> nodes = new LinkedList<TreeNode>(); //创建队列 nodes.add(pRoot); int nextLevel = 0; // 下一层点数 int toBePrinted = 1; // 当前层中还没有打印的点数 while (!nodes.isEmpty()) { ArrayList<Integer> temp = new ArrayList<Integer>(); while (toBePrinted > 0) { TreeNode pNode = nodes.peek(); temp.add(pNode.val); if (pNode.left != null) { nodes.add(pNode.left); nextLevel++; // 下一层增加一个结点 } if (pNode.right != null) { nodes.add(pNode.right); nextLevel++; } nodes.poll(); toBePrinted--; } result.add(temp); toBePrinted = nextLevel; nextLevel = 0; } return result; }}
序列化二叉树
二叉搜索树的第k个结点
数据流中的中位数
滑动窗口的最大值
矩阵中的路径
机器人的运动范围
2 0
- 剑指Offer——Java答案
- 剑指Offer——Java答案
- 剑指Offer(java答案)
- 剑指Offer(java答案)
- 剑指Offer——Python答案
- 剑指Offer——Python答案
- 剑指offer 面试题4 替换空格 java版答案
- 剑指offer题目及答案
- 《剑指offer》python答案整理(1)
- 剑指offer 面试题3 二维数组中的查找 java版答案
- 剑指offer 面试题5 从尾到头打印链表 java版答案
- 剑指offer 面试题6 重建二叉树 java版答案
- 剑指offer 面试题7 两个栈实现队列 java版答案
- 剑指offer 面试题8 旋转数组的最小值 java版答案
- 剑指offer 面试题9 斐波那契数列 java版答案
- 剑指Offer——编程题的Java实现
- 剑指Offer——反转单词顺序(Java)
- 剑指Offer——知识点储备-Java基础
- Expression Add Operators
- MFC与WinForm对比学习:简单介绍
- Leetcode #2 Add Two Numbers(medium)
- 【NOIP2016提高A组模拟9.3】被粉碎的线段树
- 用两个栈实现队列
- 剑指Offer——Java答案
- poj入门水题整理3
- 【NOIP模拟】幻象
- EXISTS ,NO EXISTS 语句
- Poj 3122 Pie【基础二分】水题
- POJ 3984迷宫问题
- 第一步:jdk的配置
- android从URL获取数据
- Mysql 存储引擎中InnoDB与Myisam的主要区别