剑指offer专题题解

1.二维数组中的查找(简单题)

思路:初始在数组的左下角进行查找,若a[i][j]>target,则说明可能在上面的行中,i--;若a[i][j]<target,则说明可能在右边的列中,j++;若a[i][j]==target,则说明找到

public class Solution {
    public boolean Find(int target, int [][] array) {
        int i=array.length-1,j=0;//刚开始在左下角
        while(i>=0&&j>=0&&j<array[0].length&&i<array.length){
            if(array[i][j]==target) return true;
            else if(array[i][j]>target) i--;//大于目标数,往上找
            else j++;//小于目标数,往右找
        }
        return false;
    }
}
View Code

2.替换空格(简单题)

思路:使用StringBuffer,String的一些方法,例如:toString(),append(),charAt()

public class Solution {
    public String replaceSpace(StringBuffer str) {
        StringBuffer s1 = new StringBuffer();
        String s2 = str.toString();
        char c = ' ';
        for(int i = 0;i < s2.length();i++){
            if(c == s2.charAt(i)) s1.append("%20");
            else s1.append(s2.charAt(i));
        }
        return s1.toString();
    }
}
View Code

3.从尾到头打印链表(多种解法)

(1) 递归方式

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    //递归方式
    ArrayList<Integer> a = new ArrayList<Integer>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode != null){
            printListFromTailToHead(listNode.next);
            a.add(listNode.val);
        }
        return a;
    }
}
View Code

(2)遍历(非递归)方式

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> a = new ArrayList<Integer>();
        while(listNode != null){
            a.add(0,listNode.val);
            listNode = listNode.next;
        }
        return a;
    }
}
View Code

4.重建二叉树

首先我们先了解一下二叉树的先序和中序和后序遍历序列

先序遍历:根节点,左子树,右子树

中序遍历:左子树,根节点,右子树

后序遍历:左子树,右子树,根节点

然后我们来模拟一下如何通过先序和中序遍历序列重建二叉树

输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}

(1)首先我们通过先序遍历序列,可以知道根节点为1,通过中序遍历序列我们可以知道根节点1的左子数为{4,7,2},右子树为{5,3,8,6}

(2)对于左子数{4,7,2},其先序遍历序列为{2,4,7},中序遍历序列为{4,7,2} ,我们可以知道该左子数的根节点为2,其左子数为{4,7},右子树为空

(3)同理我们可以知道右子树的根节点以及其左右子树

(4)按照这样的方法我们可以重建二叉树

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
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]);
        //找出i使其in[i]==pre[0]
        for(int i = 0;i < pre.length;i++){
            if(in[i] == pre[0]){
                //copyOfRange是左闭右开
                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
                root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
                break;
            }
        }
        return root;
    }
}
View Code

5.跳台阶

public class Solution {
    //动态规划 dp[n] = dp[n-1]+dp[n-2]
    public int JumpFloor(int target) {
        if(target == 1) return 1;
        if(target == 2) return 2;
        return JumpFloor(target-1) + JumpFloor(target-2);
    }
}
View Code

 

 

 

-----End------

posted @ 2019-12-20 17:35  saaas  阅读(333)  评论(0)    收藏  举报