【剑指offer】Java实现(持续更新中)
面试题3 二维数组中的查找 Leetcode--74 Search a 2D Matrix
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*Java 2 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: 3 4 Integers in each row are sorted from left to right. 5 The first integer of each row is greater than the last integer of the previous row. 6 7 For example, 8 9 Consider the following matrix: 10 11 [ 12 [1, 3, 5, 7], 13 [10, 11, 16, 20], 14 [23, 30, 34, 50] 15 ] 16 17 Given target = 3, return true. 18 本题最简单的方法循环遍历行与列 但是时间复杂度较高。 19 */ 20 class Solution { 21 public boolean searchMatrix(int[][] matrix, int target) { 22 boolean find = false; 23 int rows,cols; 24 if (matrix == null || matrix.length==0) { 25 rows = 0; 26 cols = 0; 27 } else { 28 rows = matrix.length; 29 cols = matrix[0].length; 30 } 31 32 if (matrix != null && rows > 0 && cols > 0) { 33 int row = 0; 34 int col = cols-1; 35 while(row<rows && col>=0){ 36 if(matrix[row][col]==target){ 37 find=true; 38 break; 39 } 40 41 else if(matrix[row][col]>target){ 42 col--; 43 }else{ 44 row++; 45 } 46 } 47 } 48 49 return find; 50 } 51 public static void main(String[] args) { 52 int[][] matrix1 = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 50 } }; 53 54 int[][] matrix = {}; 55 int target = 55; 56 SearchA2DMatrix cc = new SearchA2DMatrix(); 57 boolean find = cc.searchMatrix(matrix, target); 58 System.out.println(find); 59 } 60 }
面试题5 从尾到头打印链表 -------Leetcode 206题 Reverse Linked List
package easy; import java.util.Stack; import easy.ListNode; public class L206ReverseLinkedList { /* * Reverse a singly linked list. 先读入,后输出。典型的先进后出,可用栈来实现。 */ /** * Definition for singly-linked list. * * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public ListNode reverseList(ListNode head) { if (head == null) return head; Stack<Integer> myStack = new Stack<Integer>(); ListNode pNode = head; while (pNode != null) { myStack.push(pNode.val); pNode = pNode.next; } int size = myStack.size(); ListNode newHead = new ListNode(myStack.peek()); myStack.pop(); if (size == 1) return newHead; ListNode node = new ListNode(myStack.peek()); newHead.next = node; myStack.pop(); while (!myStack.empty()) { node.next = new ListNode(myStack.peek()); myStack.pop(); node = node.next; } while (newHead != null) { System.out.println(newHead.val); newHead = newHead.next; } return newHead; } public static void main(String[] args) { ListNode head1 = new ListNode(1); ListNode head2 = new ListNode(2); ListNode head3 = new ListNode(3); ListNode head4 = new ListNode(4); head1.next = head2; head2.next = head3; head3.next = head4; head4.next = null; L206ReverseLinkedList cc = new L206ReverseLinkedList(); cc.reverseList(head1); } }
面试题6:重建二叉树,由二叉树的前序遍历和中序遍历重建二叉树——Leetcode 105.Construct Binary Tree from Preorder and Inorder Traversal
package medium; //面试题6 public class L105ConstructBinaryTreefromPreorderandInorderTraversal { /* * 根据前序遍历与中序遍历重建一个二叉树 */ public TreeNode buildTree(int[] preorder, int[] inorder) { if (preorder == null || inorder == null) { return null; } int length = preorder.length; if(length==0){ TreeNode root =null; return root; } //System.out.println(length); int startPre = 0; int endPre = length - 1; int startIn = 0; int endIn = length - 1; return buildTreeCore(preorder, inorder, startPre, endPre, startIn, endIn); } public TreeNode buildTreeCore(int[] preorder, int[] inorder, int startPre, int endPre, int startIn, int endIn) { // 前序遍历的第一个结点为根节点。 int rootValue=preorder[startPre]; TreeNode root = new TreeNode(rootValue); root.left = root.right = null; System.out.println("前序遍历第一个节点"+preorder[startPre]); if (preorder[startPre] == preorder[endPre] ) if(inorder[startIn] == inorder[endIn]) { return root; } else { System.out.println("非法输入"); } //在中序遍历中找到根节点 int rootInorderIndex=startIn; while(startIn<=endIn && inorder[rootInorderIndex]!=rootValue){ rootInorderIndex++; } int leftLen=rootInorderIndex-startIn; int leftPreEnd=startPre+leftLen; if(leftLen>0){ root.left=buildTreeCore(preorder,inorder,startPre+1,leftPreEnd,startIn,rootInorderIndex-1); } if(leftLen<endPre-startPre){ root.right=buildTreeCore(preorder,inorder,leftPreEnd+1,endPre,rootInorderIndex+1,endIn); } return root; } public static void main(String[] args) { L105ConstructBinaryTreefromPreorderandInorderTraversal cc= new L105ConstructBinaryTreefromPreorderandInorderTraversal(); int[] preorder1={1,2,4,7,3,5,6,8}; int[] inorder1={4,7,2,1,5,3,8,6}; int[] preorder={1,2}; int[] inorder={2,1}; cc.buildTree(preorder, inorder); } }
面试题6-2:重建二叉树,由二叉树的中序遍历和后序遍历重建二叉树——Leetcode 106.Construct Binary Tree from Inorder and Postorder Traversal
package medium; public class L106ConstructBinaryTreefromInorderandPostorderTraversal { /* * 根据前序遍历与中序遍历重建一个二叉树 */ public TreeNode buildTree(int[] inorder, int[] postorder) { if (postorder == null || inorder == null) { return null; } int length = inorder.length; if (length == 0) { TreeNode root = null; return root; } // System.out.println(length); int startPost = 0; int endPost = length - 1; int startIn = 0; int endIn = length - 1; return buildTreeCore(inorder, postorder, startIn, endIn, startPost, endPost); } public TreeNode buildTreeCore(int[] inorder, int[] postorder, int startIn, int endIn, int startPost, int endPost) { // 后序遍历的最后一个结点为根节点。 int rootValue = postorder[endPost]; TreeNode root = new TreeNode(rootValue); root.left = root.right = null; if (postorder[startPost] == postorder[endPost]) { if (inorder[startIn] == inorder[endIn]) { return root; } else { System.out.println("非法输入"); } } // 在中序遍历中找到根节点 int rootInorderIndex = startIn; while (startIn <= endIn && inorder[rootInorderIndex] != rootValue) { rootInorderIndex++; } int leftLen = rootInorderIndex - startIn; int leftPostEnd = startPost + leftLen-1; if (leftLen > 0) { root.left = buildTreeCore(inorder, postorder, startIn, rootInorderIndex - 1, startPost, leftPostEnd); } if (leftLen < endPost - startPost) { root.right = buildTreeCore(inorder, postorder, rootInorderIndex + 1, endIn, leftPostEnd + 1, endPost - 1); } return root; } public static void main(String[] args) { L106ConstructBinaryTreefromInorderandPostorderTraversal cc = new L106ConstructBinaryTreefromInorderandPostorderTraversal(); int[] inorder = { 4, 7, 2, 1, 5, 3, 8, 6 }; int[] postorder={ 7, 4, 2, 5, 8, 6, 3, 1 }; cc.buildTree( inorder,postorder); } }
面试题7 用两个栈,实现队列-----Leetcode 232题 Implement Queue using Stacks
package easy; import java.util.Stack; public class L232ImplementQueueUsingStacks { Stack<Integer> queue = new Stack(); public void push(int x) { Stack<Integer> stack = new Stack(); while (!queue.empty()) { stack.push(queue.pop()); } queue.push(x); while (!stack.empty()) { queue.push(stack.pop()); } } public int pop() { return queue.pop(); } public int peek() { return queue.peek(); } public boolean empty() { return queue.empty(); } public static void main(String[] args) { MyQueue obj = new MyQueue(); obj.push(2); obj.push(1); obj.push(3); obj.push(4); int param_2 = obj.pop(); int param_3 = obj.peek(); boolean param_4 = obj.empty(); System.out.println("pop:"+param_2); System.out.println("peek:"+param_3); System.out.println("empty:"+param_4); } }
面试题7-2 用两个队列,实现栈-----L225题 Implement Stacks using Queue
package easy; import java.util.LinkedList; import java.util.Queue; public class L225_ImplementStackUsingQueues { /* * 用两个栈实现队列 先入先出 * * Implement the following operations of a stack using queues. */
Queue<Integer> queue1 = new LinkedList<Integer>(); Queue<Integer> queue2 = new LinkedList<Integer>(); // push(x) -- Push element x onto stack. public void push(int x) { if (queue1.isEmpty() && queue2.isEmpty()) { queue1.add(x); } else if (!queue1.isEmpty()) { queue1.add(x); } else { queue2.add(x); } } // pop() -- Removes the element on top of the stack. public int pop() { int size1 = queue1.size(); int size2 = queue2.size(); if (size1 > 0) { while (size1 > 1) { queue2.add(queue1.poll()); size1--; } return queue1.poll(); } else if (size2 > 0) { while (size2 > 1) { queue1.add(queue2.poll()); size2--; } return queue2.poll(); } else { System.out.println("栈为空"); } return 0; } // top() -- Get the top element. public int top() { int size1 = queue1.size(); int size2 = queue2.size(); int x=0; if (size1 > 0) { while (size1 > 1) { queue2.add(queue1.poll()); size1--; } x=queue1.peek(); queue2.add(queue1.poll()); } else if (size2 > 0) { while (size2 > 1) { queue1.add(queue2.poll()); size2--; } x=queue2.peek(); queue1.add(queue2.poll()); } else { System.out.println("栈为空"); } return x; } // empty() -- Return whether the stack is empty. public boolean empty() { int size = queue1.size() + queue2.size(); return size > 0 ? false : true; } public static void main(String[] args) { //["MyStack","push","push","push","top", //"pop","top","pop","top","empty","pop","empty"] L225_ImplementStackUsingQueues obj = new L225_ImplementStackUsingQueues(); obj.push(1); System.out.println("top1:" +obj.top()); obj.push(2); System.out.println("top2:" +obj.top()); obj.push(3); System.out.println("top3:" +obj.top()); System.out.println("pop:" +obj.pop() ); System.out.println("top:" +obj.top()); System.out.println("pop:" +obj.pop() ); System.out.println("top:" +obj.top()); System.out.println("empty:" + obj.empty()); System.out.println("pop:" +obj.pop() ); System.out.println("empty:" + obj.empty()); } }
面试题8:旋转数组的最小数字—leetcode 153题 Find Minimum in Rotated Sorted Array
class Solution { public int findMin(int[] nums) { int min=nums[0]; int len=nums.length; int low=0; int high=len-1; int mid=(low+high)/2; if(nums[low]<nums[high]){ return nums[low]; } while(low<=high){ if(high-low==1 || high==low){ System.out.println("min:"+min); return nums[high]<=nums[high] ? nums[high]:nums[low]; } if(nums[mid]>nums[high]){ min=nums[high]; low=mid; }else{ min=nums[mid]; high=mid; } mid=(low+high)/2; } return min; } }
面试题9:菲波那切数列
package jianzhiOffer; public class I9Fibonacci { public int calFi1(int n) { // 递归 if (n == 0) { return 0; } if (n == 1) { return 1; } return calFi1(n - 1) + calFi1(n - 2); } public int calFi2(int n) { // 循环 if (n == 0) { return 0; } if (n == 1) { return 1; } int one = 0; int two = 1; int sum = 0; for (int i = 2; i <= n; i++) { sum = one + two; one = two; two = sum; } return sum; } public static void main(String[] args) { I9Fibonacci cc = new I9Fibonacci(); int sum1 = cc.calFi1(3); int sum2 = cc.calFi2(3); System.out.println(sum1 + ":" + sum2); } }
面试题10:二进制中1的个数——剑指OfferP78 ~~~L191题 Number of 1 Bits
package easy; public class L191NumberOf1Bits { // you need to treat n as an unsigned value //将一个整数减去一个1,这个整数的二进制变化是:最右面的1变为0,这一位之后的所有位变为1. //如1100 减去一为1011. //减1之后的整数与原来的整数做与运算,会把原整数最右面一位变为0. //1011 & 1100=1000 public int hammingWeight(int n) { int number=0; while(n!=0){ number++; n=(n-1)&n; } return number; } //解法2 较慢的解法,如果n&1结果为1这表示n的最后一位为1,count++;之后将1左移,判断前面位。 public int solu2(int n){ int number=0; int flag=1; while(flag!=0){ if((n & flag) !=0){ number++; } flag=flag<<1; } return number; } public static void main(String[] args) { L191NumberOf1Bits cc= new L191NumberOf1Bits(); int number=cc.hammingWeight(2); System.out.println(number); } }
面试题11:数值的整数次方——Leetcde 50.Pow(x, n) 详解
面试题14:调整数组顺序使奇数位于偶数前面——Leetcode 328. Odd Even Linked List 详解
面试题15:链表中倒数第k个结点~~~~Leetcode 19. Remove Nth Node From End of List.详解
面试题16:反转链表~~~~~Leetcode 92. Reverse Linked List II 详解
Leetcode 206.Reverse Linked List 详解
面试题17:合并两个排序的链表~~~~~Leetcode 21. Merge Two Sorted Lists 详解
面试题20:顺时针打印矩阵~~~~Leetcode 54.Spiral Matrix 详解
59题 Spiral MatrixII 详解
面试题25:二叉树中和为某一值的路径~~~~Leetcode 112 Path Sum 详解
Leetcode 113 PathSumII 详解
面试题29:数组中出现次数超过一半的数字~~~~~Leetcode 169.Majority Element 详解
面试题33:把数组排成最小的数~~~~~Leetcode 179.Largest Number 详解
面试题37:两个链表中的第一个公共节点~~~~~Leetcode 160. Intersection of Two Linked Lists 详解
面试题39:二叉树的深度~~~~~Leetcode 110. Balanced Binary Tree 详解
面试题50:把字符串变成整数(atoi函数)~~~~Leetcode 8.String to Integer (atoi) 详解
面试题51:树中两个结点的最低公共祖先~~~~~~Leetcode 235. Lowest Common Ancestor of a Binary Search Tree详解
Leetcode 236.Lowest Common Ancestor of a Binary Tree 详解