leetcode算法题-剑指Offer篇(1)
1、找出数组中重复的数字
1.1 题目描述:
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1
的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
1.2 题解
1.2.1 利用map结构
public int findRepeatNumber(int[] nums) {
if (nums.length == 0)
return -1;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (!map.containsKey(nums[i]))//若map中不存在,则存入
map.put(nums[i], 1);
else
return nums[i]; //若存在,则返回值
}
return -1;
}
1.2.2 利用set
public int findRepeatNumber2(int[] nums) {
if (nums.length == 0)
return -1;
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
if (!set.add(nums[i]))//add方法返回boolean值,如果存在返回true,不存在返回false
return nums[i];
}
return -1;
}
1.2.3 直接修改数组。
对数组进行重新排序,使得数字i在下标为i的位置。比如下标为i的数字如果不是i的,而是j的话,我们就将其与下标为j的数字交换。否则,返回i。
public int findRepeatNumber(int[] nums) {
int temp;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != i) {//下标为i的数字不等于i,则进行交换。假设num[i]=j;
if (nums[i] == nums[nums[i]])//若下标为i的数等与下标为j的数,则表示数字重复,返回
return nums[i];
temp = nums[i];//以下是将下标为i的数字与下标为j的数进行交换,保证。下标为i的数等于i
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
2、二维数组中的查找
2.1题目描述
在一个 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] ]
给定 target = 5,返回 true。 给定 target = 20,返回 false。
2.2 题解
2.2.1 暴力解法,遍历
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;
}
}
}
}
2.2.2 左下角标志数法
标志数引入: 此类矩阵中左下角和右上角元素有特殊性,称为标志数。
左下角元素: 为所在列最大元素,所在行最小元素。
右上角元素: 为所在行最大元素,所在列最小元素。
标志数性质: 将 matrix 中的左下角元素(标志数)记作 flag ,则有:
若 flag > target ,则 target 一定在 flag 所在行的上方,即 flag 所在行可被消去。
若 flag < target ,则 target 一定在 flag 所在列的右方,即 flag 所在列可被消去。
本题解以左下角元素为例,同理,右上角元素 也具有行(列)消去的性质。
public boolean findNumberIn2DArray2(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int rows =matrix.length;
int cols=matrix[0].length;
int flag=0;//左下角数作为标志数
int row=rows-1,col=0;
while(row>=0&&col<cols){
flag=matrix[row][col];
if(flag==target)
return true;
else if(flag<target)//如果比标志数大。则列数加1;
col++;
else if(flag>target)//若比标志数小,在行数减一
row--;
}
return false;
}
3.替换空格
1.1 题目描述
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 示例 1: 输入:s = “We are happy.”
输出:“We%20are%20happy.”
2.2 题解
2.2.1 遍历替换
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;
}