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