剑指Offer总结:
1、二维数组查找某个整数。
public class Solution {
public boolean Find(int target, int [][] array) {
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;
}
}
2、请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
import java.lang.StringBuffer;
import java.lang.String;
public class Solution {
public String replaceSpace(StringBuffer str) {
StringBuffer sb = new StringBuffer();
int n=str.length();
for(int i=0;i<n;i++){
if(str.charAt(i)==' '){
sb.append("%20");
}else{
sb.append(str.charAt(i));
}
}
String s = sb.toString();
return s;
}
}
3、从尾到头打印链表
方法1:
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
ListNode node = listNode;
while(node!=null){
list.add(0,node.val); //此方法每次将链表结点插入到ArrayList的0位置处
node = node.next;
}
return list;
}
}
方法2:
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList();
Stack<Integer> s = new Stack();
if(listNode==null){
return list;
}
while(listNode!=null){
s.push(listNode.val);
if(listNode.next==null){
break;
}else{
listNode=listNode.next;
}
}
while(s.size()!=0){
int x = s.pop();
list.add(x);
}
return list;
}
}
4、重建二叉树:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
//树,用递归
//前序[1][2,4,7][3,5,6,8] 根左右 left1、right1表示前序遍历的下标
//中序[4,7,2][1][5,3,8,6] 左根右 left2、right2表示中序遍历的下标
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre.length == 0 || in.length == 0) {
return null;
}
TreeNode root = new TreeNode(pre[0]);
for (int i = 0; i < in.length; i++) { // 在中序遍历中找到前序的根
if (in[i] == pre[0]) {
// 左子树,注意 copyOfRange 函数,左闭右开
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
// 右子树,注意 copyOfRange 函数,左闭右开
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
break;
}
}
return root;
}
}
5、用两个栈实现一个队列
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.size()==0){
while(stack1.size()!=0){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
6、把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
//二分法
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0) return 0;
int low=0;
int high=array.length-1;
int mid;
while(low<high){
if(array[low]<array[high])
return array[low];
mid=(low+high)/2;
if(array[mid]>array[low])
low=mid+1;
else if(array[mid]<array[high])
high=mid;
else
low++;
}
return array[low];
}
}
7、斐波那契数列
public class Solution {
public int Fibonacci(int n) {
if(n==0) return 0;
if(n==1) return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
}
8、跳台阶
public class Solution {
public int JumpFloor(int target) {
if(target==0) return 1;
if(target==1) return 1;
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
9、变态跳台阶
//f(n)=f(n-1)+f(n-2)+...+f(1)
//f(n-1)=f(n-2)+f(n-3)+...+f(1)
//两式相加,f(n)=2^n-1,利用左移乘2
//口诀:左移乘2,右移除2
public class Solution {
public int JumpFloorII(int target) {
return 1<<(target-1);
}
}
10、矩阵覆盖(斐波那契数列)
public class Solution {
public int RectCover(int target) {
if (target==0) return 0;
if(target<2) return 1;
int[] a = new int[target];
a[0]=1;
a[1]=2;
for(int i=2;i<target;i++){
a[i]=a[i-1]+a[i-2];
}
return a[target-1];
}
}
11、二进制中1的个数
public class Solution {
public int NumberOf1(int n) {
int count=0;
while(n!=0){
count++;
n=n&(n-1);
}
return count;
}
}
12、数值的整数次方
public class Solution {
public double Power(double base, int exponent) {
if(base==0&&exponent==0) return 0;
if(exponent<0){
base=1/base;
exponent=-exponent;
}
double sum=1;
for(int i=0;i<exponent;i++){
sum=sum*base;
}
return sum;
}
}
13、调整数组顺序使奇数位于偶数前面
方法1:
public class Solution {
public void reOrderArray(int [] array) {
int[] a = new int[array.length];
int count=0;
for(int i=0;i<array.length;i++){
if(array[i]%2!=0){
a[count]=array[i];
count++;
}
}
for(int i=0;i<array.length;i++){
if(array[i]%2==0){
a[count]=array[i];
count++;
}
}
for(int i=0;i<a.length;i++){
array[i]=a[i];
}
}
}
方法2:
public class Solution {
public void reOrderArray(int [] array) {
int i=0,j;
while(i<array.length){
while(i<array.length&&array[i]%2!=0){
i++;
}
j=i+1;
while(j<array.length&&array[j]%2==0){
j++;
}
if(j<array.length){
int temp=array[j];
for(int k = j - 1; k >= i; k--){
array[k + 1] = array[k];
}
array[i++] = temp;
}else{
break;
}
}
}
}
14、链表中倒数第k个结点
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head==null || k==0) return null;
ListNode left=head,right=head;
for(int i=0; i<k; i++){
if(right==null) return null; //这里要加上判断,否则出现空指针异常
right=right.next;
}
while(right!=null){
left=left.next;
right=right.next;
}
return left;
}
}
15、反转链表
import java.util.Stack;
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode dynmy = null;
ListNode current=head;
ListNode last= null;
while(current!=null){
last=current.next;
current.next=dynmy;
dynmy=current;
current=last;
}
return dynmy;
}
}
16、合并两个有序链表
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode head= new ListNode(0);
ListNode current=head;
while(list1!=null && list2!=null){
if(list1.val<=list2.val){
current.next=list1;
list1=list1.next;
}else{
current.next=list2;
list2=list2.next;
}
current=current.next;
}
if(list1!=null){
current.next=list1;
}
if(list2!=null){
current.next=list2;
}
return head.next;
}
}
17、树的子结构
public class Solution {
public boolean HasSubtree(TreeNode A,TreeNode B) {
//树的问题,肯定递归解决
//三种情况,A根是B根,A左子树是B,A右子树是B
if (A==null || B==null){
return false;
}
return issubtree(A,B) || HasSubtree(A.left,B) || HasSubtree(A.right,B);
}
public boolean issubtree(TreeNode A,TreeNode B){
//何时为ture或false
if(B==null) return true;
if(A==null || A.val!=B.val) return false;
return issubtree(A.left,B.left)&&issubtree(A.right,B.right);
}
}
18、二叉树镜像
public class Solution {
public void Mirror(TreeNode root) {
if(root==null) return;
if(root.left!=null || root.right!=null){
TreeNode temp;
temp=root.left;
root.left=root.right;
root.right=temp;
}
if(root.left!=null) Mirror(root.left);
if(root.right!=null) Mirror(root.right);
}
}
19、顺时针打印数组
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(matrix == null) return list;
int up = 0;
int down = matrix.length-1;
int left = 0;
int right = matrix[0].length-1;
while(true){
for(int i=left;i<=right;i++) //先输出最上面一行,然后up++一次
list.add(matrix[up][i]);
if(++up > down) break; //向右遍历完向下遍历,需判断下边界是否越界
for(int i=up;i<=down;i++)
list.add(matrix[i][