# 数据结构和算法类目

数据结构
剑指Offer
1.找出数组中重复的数字。(数组)
要求:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
思路:由于只需要找出数组中任意一个重复的数字,因此遍历数组,遇到重复的数字即返回。为了判断一个数字是否重复遇到,使用集合存储已经遇到的数字,如果遇到的一个数字已经在集合中,则当前的数字是重复数字。
初始化集合为空集合,重复的数字 repeat = -1 遍历数组中的每个元素: 将该元素加入集合中,判断是否添加成功 如果添加失败,说明该元素已经在集合中,因此该元素是重复元素,将该元素的值赋给 repeat,并结束遍历 返回 repeat
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set=new HashSet<Integer>();
int repeat=-1;
for(int num:nums){
if(!set.add(num)){
repeat=num;
break;
}
}
return repeat;
}
}
2.替换空格(字符串)
要求:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
思路:由于每次替换从 1 个字符变成 3 个字符,使用字符数组可方便地进行替换。建立字符数组地长度为 s 的长度的 3 倍,这样可保证字符数组可以容纳所有替换后的字符。
class Solution{
public String replaceSpace(String s) {
int length = s.length();
char[] array = new char[length * 3];
int size = 0;
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == ' ') {
array[size++] = '%';
array[size++] = '2';
array[size++] = '0';
} else {
array[size++] = c;
}
}
String newStr = new String(array, 0, size);
return newStr;
}
}
3.二维数组的查找(数组)
要求:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 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]
]
线性查找法:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int rows = matrix.length, columns = matrix[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (matrix[i][j] == target) {
return true;
}
}
}
return false;
}
}
4.从尾到头打印链表(栈 链表 数组)
要求:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
题解中Stack中元素类型为ListNode,可以替换为直接保存val的类型Integer
class Solution {
public int[] reversePrint(ListNode head) {
Stack<Integer> stack = new Stack<>();
while (head != null) {
stack.push(head.val);//将链表的值压栈
head = head.next;
}
int size = stack.size();
int[] array = new int[size];
for (int i = 0; i < size; i++) {
array[i] = stack.pop();//将栈中的数据以后进相处的方式放入数组
}
return array;
}
}
5.旋转数组中的最小数字(数组)
要求:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
class Solution {
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while (i < j) {
int m = (i + j) / 2;
if (numbers[m] > numbers[j]) i = m + 1;
else if (numbers[m] < numbers[j]) j = m;
else j--;
}
return numbers[i];
}
}