学习剑指offer 第五天
04 二维数组中的查找
- 题目描述
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
比如:二维矩阵
[
[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]
]
- 解析:
该二维数组可以看成是一个倾斜的二叉排序树,将右上角的点看作是树根,向左是变小,向下时变大,就可以根据二叉排序树的性质找到元素。
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix.length == 0 || matrix[0].length == 0) return false;
//根据二叉排序树的性质
int m = 0, n = matrix[0].length - 1;
while(m < matrix.length && n >= 0){
if(matrix[m][n] == target) return true;
if(matrix[m][n] > target){
n--;
}else{
m++;
}
}
return false;
}
11. 旋转数字的最小数字
- 题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
public int minArray(int[] numbers) {
if(numbers.length == 1) return numbers[0];
//找到第一个递减位置
for(int i = 1; i < numbers.length; i++){
if(numbers[i] < numbers[i - 1]) return numbers[i];
}
//如果该元素为递增元素,则最小值为第一个数字
return numbers[0];
}
50 第一个只出现一次的字符
- 题目描述
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 - 解析
public char firstUniqChar(String s) {
//使用linkedhashmap保存插入顺序
Map<Character, Boolean> record = new LinkedHashMap<>();
//true为已经存在 false为存在多个
for(char c : s.toCharArray()){
record.put(c, !record.containsKey(c));
}
for(Map.Entry<Character, Boolean> entry : record.entrySet()){
if(entry.getValue() == true) return entry.getKey();
}
return ' ';
}
因为字符只有26个,是固定长度,所以采用了数组
public char firstUniqChar(String s) {
int[] record = new int[26];
char[] str = s.toCharArray();
for(char c : str){
record[c - 'a']++;
}
for(char c : str){
if(record[c - 'a'] == 1) return c;
}
return ' ';
}