《剑指Offer》Java实现(01-10题)
01 - 二维数组中的查找
题目描述
考点
- 二叉搜索树
- 变种二分
解题思路
其实从右上角往下看就是一个含有重复值的二叉搜索树【假设要查找7】
首先选取右上角的数字
- 如果数字 = 要查找的数字,查找过程结束
- 如果该数字 > 要查找的数字,剔除这个数字所在的列
- 如果该数字 < 要查找的数字,剔除这个数字所在的行
每一步都这样缩小范围,直到找到要查找的数字或者查找的范围是空的结束
代码实现
public static boolean find(int[][] matrix, int rows, int columns, int target) {
boolean found = false;
if (matrix != null && rows > 0 && columns > 0) {
int row = 0;
int column = columns - 1; // 定位到右上角元素
while (row < rows && column > 0) {
if (matrix[row][column] == target) {
found = true;
break;
} else if (matrix[row][column] > target) {
column -= 1; // 剔除一列
} else {
row += 1; // 剔除一行
}
}
}
return found;
}
02 - 替换空格
题目描述
业务中肯定是用replace()
方法直接就完事了,这里主要介绍一下双指针的实现方式
解题思路
- 先遍历一遍字符串,得到空格数,并计算出替换之后的字符串的总长度
- 从后面开始复制和替换,先准备两个指针P1 & P2,P1指向原始子串的末尾,P2指向替换之后字符串的末尾
- 向前移动P1,逐个将他指向的字符复制到P2指向的位置,直到碰到第一个空格位置,P1向前移动一格,P2移动三格
- P1 & P2指向同一位置时,替换完成
代码实现
/**
* 替换空格为%20
*
* @param chs 字符数组
* @param length 总容量
*/
public void replaceBlack(char[] chs, int length) {
if (chs == null || length <= 0) {
return;
}
int originalLength = 0; // 实际长度
int numberOfBlack = 0; // 空格数
for (char ch : chs) {
originalLength += 1;
if (ch == ' ') {
numberOfBlack += 1;
}
}
int newLength = originalLength + 2 * numberOfBlack; // 替换之后的长度
if (newLength > length) {
// 当前的长度容量放不下,直接返回
return;
}
int p1 = originalLength;
int p2 = newLength;
while (p1 >= 0 && p2 > p1) {
if (chs[p1] == ' ') {
chs[p2--] = '0';
chs[p2--] = '2';
chs[p2--] = '%';
} else {
chs[p2--] = chs[p1];
}
p1--;
}
}
03 - 从尾到头打印链表
题目描述
考点
- 栈
- 尾递归
解题思路
- 因为遍历的顺序是从头到尾,而输出的顺序是从尾到头的,很显然符合先进后出的特点,这自然而然想到可以用栈来实现这种顺序
- 每经过一个节点的时候,将这个节点放入栈中,当遍历完成之后,从栈顶逐个赋值到数组中即可
- 而递归的本质是栈,因此可以使用尾递归的方式,得到结果
代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
if (head == null) {
return new int[0];
}
Stack<Integer><