3.数组中重复的数字
题目一描述
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
解题思路
(这一题牛客没有,格式就随便写的)
一、由题干,长度为n,数字都在0到n-1范围内可知,将数组数字和序号对应,即可快速查找到重复数字(牛客)
public class Main {
/**
*
* 首先是将数字和下标对应,就可以快速查找是否存在重复值
*
* */
public boolean duplicate(int[] nums, int length, int[] duplication) {
if (nums == null || length <= 0) //边界值判断:判断数组是否为空,长度是否小于0
return false;
for (int i = 0; i < length; i++) {
while (nums[i] != i) { // 如果当前的值和序号不同,则执行,否则该数在合适的位置,遍历下一个
if (nums[i] == nums[nums[i]]) { // 如果该数和该数序号下的值相同,就返回该值
duplication[0] = nums[i];
return true;
}
swap(nums, i, nums[i]); // 否则,将该数字放到他所该在的位置
}
}
return false;
}
private void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
二、先排序,再找重复值(数字和后一位相同)(剑指)
三、哈希表(剑指)(这个方法写一遍加深哈希表记忆)其实第一个思路也是哈希表思路。
题目二描述
在一个长度为 n+1 的数组里的所有数字都在 1 到 n 的范围内。数组中一定有至少一个重复数字,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
解题思路
一、同题目一,使用新数组复制一份之前的数组使用
二、折半查找法,统计数字数目。根据题意一定至少有一个数字重复,折半统计某个区间不断逼近,即可找到这个数(写一遍加深记忆),值得注意的是,该方法有可能无法找到所有的重复数字。
public class Main(){
public boolean duplicate3(int[] nums, int length, int[] duplication){
if(nums == null || length <= 0) //length = n + 1
return false;
int start = 1;
int end = length - 1; // n
while(end != start){
int middle = (end+start)/2;
int c = count(start,middle,nums,length);
if(c>middle-start+1)
end = middle;
else
start = middle+1;
if(start == end){
duplication[0]=start;
return true;
}
}
return false;
}
private int count(int start, int end, int[] nums, int length){
int c = 0;
for(int i=0; i<length; i++){
if(nums[i]>=start && nums[i]<=end)
c++;
}
return c;
}
}
4.二维数组中的查找
题目描述
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。
解题思路
一开始我的想法是这样的想的太简单了……
一、先横向查找,找到大于该数的列,再纵向查找前一列,直到该数。如果上一个等于下一个,或者上一个和下一个都不等于该数,则返回false,找到值则返回true。查找的方法可以采用(自己)(×)
二、该数组有个特性,就是某个值,小于他的数在他左边,大于他的数在他下面(也可以说大于他的数在他右边,小于他的数在他上边),所以从左下角或者右上角开始查找。从右上角开始,和默认值比较,如果默认值小,则往左走,如果大则往下走,直到左下角即可。(剑指,牛客)
public class Solution {
public boolean Find(int target, int [][] array) {
int rowsline = array.length;
int columnline = array[0].length;
int i=0,j=columnline-1;
while (i<=rowsline-1 && j>=0){
if(array[i][j]==target)
return true;
else if(array[i][j]>target)
j = j-1;
else
i = i+1;
}
return false;
}
public static void main(String args[]){
int[][] array = {{1,5,9,13},{2,6,10,14},{3,7,11,15},{4,8,12,16}};
int target = 10;
Solution s = new Solution();
System.out.println(s.Find(target, array));
}
}
5.替换空格
题目描述
将一个字符串中的空格替换成 "%20"
解题思路
牛客里面使用StringBuffer来存储给定字符串,首先要明确几个StringBuffer的操作
// StringBuffer创建实例
StringBuffer str = new StringBuffer("abc");
// 取StringBuffer的长度
int l = str.length();
// 取StringBuffer中对应的元素
char c =str.CharAt(0);
// 向StringBuffer中追加String或者char
str.append("def");
str.append('g');
// 修改StringBuffer的值
str.setCharAt(1, c);
使用StringBuffer之后,这道题可以采用指针的办法,首先根据空格的数量在字符串后追加2倍的空字符串,P1指向原本的最后一个位置,P2指向新StringBuffer的最后一位,然后再从后往前遍历,遍历不是空字符串,从P1赋值到P2,如果为空,倒叙添加"0""2""%"三个字符。
public class Solution {
public String replaceSpace(StringBuffer str) {
if (str == null)
return "false";
int P1 = str.length() - 1;
for (int i=0;i<=P1;i++){
if (str.charAt(i) == ' '){
str.append(" ");
}
}
int P2 = str.length() - 1;
for (int i=P1;i>-1;i--){
char c = str.charAt(i);
if (c == ' '){
str.setCharAt(P2--, '0');
str.setCharAt(P2--, '2');
str.setCharAt(P2--, '%');
}
else
str.setCharAt(P2--,c);
}
String str2 = str.toString();
return str2;
}
public static void main(String args[]){
StringBuffer str = new StringBuffer("");
Solution s = new Solution();
System.out.println(s.replaceSpace(str));
}
}