大家好,我叫小伍,今天开始正式更新“剑指Offer”系列的编程题,本系列使用的语言是java,希望我的讲解可以帮助到大家。
刷题地址:
剑指Offer在线刷题
题目:找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,
但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
备注:如果看不清题目或者想练习这道题的小伙伴,可以直接点击下面的地址
数组中重复的数字
**解法1:**使用hash表
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set=new HashSet<Integer>();//定义hash表
//set表示每次添加数字不可以重复
int res=-1;//如果找不到重复的元素就返回-1
for(int num:nums){
if(!set.add(num)){//如果add失败了,那么也就找到重复的元素
res=num;
break;
}
}
return res;
}
}
**解法2:**先排序然后再找重复的元素
class Solution {
public int findRepeatNumber(int[] nums) {
//先排序,再比较
Arrays.sort(nums);
for(int i = 0;i<nums.length-1;i++){
if(nums[i] == nums[i+1]){
return nums[i];
}
}
//找不到重复的元素就返回-1
return -1;
}
}
**解法3:**下标与对应值相等继续不然不停交换(这种解法比较新颖,大家可以尝试着进行学习,但是我个人不太建议大家在实际的面试中尝试这种解法,因为需要冒一定的风险,如果第一次编译没有解决这个题的话,心态可能会收到影响,所以大家最好还是使用“求稳”的解法!)
class Solution {
public int findRepeatNumber(int[] nums) {
if(nums.length == 0){
return -1;
}
for(int i = 0; i<nums.length;i++){
if(nums[i]<0 || nums[i]>nums.length-1){
return -1;
}
}
for(int i = 0;i<nums.length;i++){
while(nums[i] != i){
if(nums[i] == nums[nums[i]]){
return nums[i];
}
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -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。
限制:
0 <= n <= 1000
0 <= m <= 1000
刷题地址:
二维数组中的查找
**解法1:**我们先判断数组是否为空,(注意:既要判断二维数组也要判断一维数组),然后我们取矩阵右上角的元素作为标准,并进行比较,如果目标值大于标准则“行加一”,如果目标值小于标准则“列减一”。
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//先判断数组是否为空,包括一维数组判空和二维数组判空
if(matrix ==null||matrix.length==0||(matrix.length==1&&matrix[0].length==0)){
return false;
}
int i=0,j=matrix[0].length-1;//这表示右上角的元素
while(i<matrix.length&&j>=0){
if(target==matrix[i][j]){
return true;
}else if(target>matrix[i][j]){
i++;
}else{
j--;
}
}
return false;
}
}
备注:在这道题中,其实如果直接使用双重for循环也是可以解决问题,但是这样就不符合题意了,题中明确说明了“每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序”,所以如果直接使用暴力解法进行解题的话,那么面试有可能会不妙!
题目:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
限制:
0 <= s 的长度 <= 10000
刷题地址:
替换空格
**解法1:**直接使用jdk中的api方法。这种解法虽然可以解决这道题,但是运行的时间较长,不推荐大家使用。(但是这种解法是必须要会的!)
class Solution {
public String replaceSpace(String s) {
s=s.replaceAll(" ","%20");
return s;
}
}
**解法2:**先把字符串转换为字符数组,然后再进行替换。
class Solution {
public String replaceSpace(String s) {
int n=s.length();
char[] array=new char[n*3];//因为原来的空格是一个字符
//替换后的%20变成了3个字符,因此我们设置的长度变成了原来的三倍!
int size=0;
for(int i=0;i<n;i++){
char c=s.charAt(i);
if(c==' '){
array[size++]='%';
array[size++]='2';
array[size++]='0';
}else{
array[size++]=c;
}
}
String news=new String(array,0,size);
return news;
}
}
小总结:
练习编程题是一个枯燥的过程,但也是一个修炼内力的过程,没有扎实的算法功底,那么在工作中很有可能会一直成为底层的程序员(负责CRUD),这一点我深有体会。我会持续为大家更新“剑指Offer”解题系列,希望我的博客可以帮助到大家,最后祝每一个看到我博客的小伙伴都开心快乐的度过每一天。