劍指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]對應於右子樹繼續上一個過程,最終得以重建二叉樹。
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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