剑指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]对应于右子树继续上一个过程,最终得以重建二叉树。