剑指OFFER编程题全集--Java版本实现

 

剑指offer --Python版本的实现:

剑指offer(1/3)第一大部分

剑指offer(2/3)第二大部分

剑指offer(3/3)第三大部分

 

1.二维数组中的查找

题目描述

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]


给定 target = 5,返回 true。

给定 target = 20,返回 false。
 

从左下角开始搜索,如果该数大于目标数,则 行数 减去 1,向上搜索小的数值;

如果小于目标数,则 列数 + 1 ,向左边搜索,搜索更大的数值

public class Solution {
    public boolean Find(int target, int [][] array) {
        int row = array.length-1;
        int col = 0;  // 从左下角开始搜索,array.length 表示行的大小,array[0].length表示列的大小
        
        while (row >= 0 && col <= array[0].length-1){
            if (array[row][col] == target){
                return true;
            }else if(array[row][col] > target){
                row--;
            }else{
                col++;
            }
            
        }
        return false;

    }
}

 

2.替换空格

请实现一个函数,将一个字符串中的空格替换成“%20”。
例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。  

第一种方法:新开一个内存空间

public class Solution {
    public String replaceSpace(StringBuffer str) {
        //创建一个新的空间
        StringBuffer out = new StringBuffer();
        for (int i = 0; i < str.length(); i++){
            char a = str.charAt(i);
            if (a == ' '){
                out.append("%20");
            }else{
                out.append(a);
            }
        }
        return out.toString();
    	
    }
}

第二种方法:不开辟新的空间,从后面往前面移动

public class Solution {
    public String replaceSpace(StringBuffer str) {
    	// 计算空格的数量
        int spaceNum = 0;
        for (int i = 0; i < str.length(); i++){
            char a = str.charAt(i);
            if (a == ' '){
                spaceNum ++;
            }
        }
        
        // 开辟空间
        int oldIndex = str.length()-1; // 原字符串的下标
        int newLength = str.length() + spaceNum * 2;
        int newIndex = newLength -1;
        str.setLength(newLength); // 重新设置字符串的长度
        
        while(newIndex >= 0){
            if (str.charAt(oldIndex) != ' '){
                str.setCharAt(newIndex, str.charAt(oldIndex));
                oldIndex --;
                newIndex --;
            }else{
                str.setCharAt(newIndex--, '0');
                str.setCharAt(newIndex--, '2');
                str.setCharAt(newIndex--, '%');
                oldIndex--; // 只进行一次减 1
            }
        }
        
        return str.toString();
        
        
    }
}

 

3.从尾到头打印单链表值

第一种:使用数组

/**
*    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> res = new ArrayList();
        if (listNode == null){
            return res;
        }
        
        while(listNode != null){
            res.add(listNode.val);
            listNode = listNode.next;
            
        }
        ArrayList<Integer> ress = new ArrayList();
        for(int i = res.size()-1; i >= 0; i--){
            ress.add(res.get(i));
        }
        return ress;
        
    }
}

第二种方法:使用栈

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
import java.util.Stack;

public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        // 使用栈结构实现
        ArrayList<Integer> res = new ArrayList();
        if (listNode == null){
            return res;
        }
        Stack<Integer> stack = new Stack();
        while (listNode != null){
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        
        while (!stack.isEmpty()){
            res.add(stack.pop());
            
        }
        return res;
        
        
    }
}

4.根据前序,中序构造二叉树


根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]  中, 左, 右
中序遍历 inorder = [9,3,15,20,7]   左, 中, 右
返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
思路:前序的第一个元素是根结点的值,在中序中找到该值,中序中该值的左边的元素是根结点的左子树,右边是右子树,然后递归的处理左边和右边

利用二叉树前序遍历和中序遍历的特性。前序遍历的第一个值一定为根节点,对应于中序遍历中间的一个点。在中序遍历序列中,这个点左侧的均为根的左子树,这个点右侧的均为根的右子树。这时可以利用递归,分别取前序遍历[1:i+1]和中序遍历的[:i]对应与左子树继续上一个过程,取前序遍历[i+1:]和中序遍历[i+1]对应于右子树继续上一个过程,最终得以重建二叉树。
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章