1.数组中重复的数字
题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如
Input:
{2, 3, 1, 0, 2, 5}
Output:
2
解题思路: 因为数组中的数字都在0~n-1的范围内,所以,如果数组中没有重复的数,那当数组排序后,数字i将出现在下标为i的位置。现在我们重排这个数组,从头到尾扫描每个数字,当扫描到下标为i的数字时,首先比较这个数字(记为m)是不是等于i。如果是,则接着扫描下一个数字;如果不是,则再拿它和m 位置上的数字进行比较,如果它们相等,就找到了一个重复的数字(该数字在下标为i和m的位置都出现了),返回true;如果它和m位置上的数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置。接下来再继续循环,直到最后还没找到认为没找到重复元素,返回false。
public boolean duplication(int[] numbers, int length, int[] duplication){
//如果输入的数组为空,直接返回false
if(numbers == null || length<=0)
return false;
//从头到尾扫描数组
for(int i=0; i<length; i++){
//如果数组不在1——n-1的范围内,直接返回false
if(numbers[i]<0 || numbers[i]>=length)
return false;
//当数组中某个元素不等于其下标时,分为两种情况
while(numbers[i]!=i){
//如果这个元素与以这个元素值为下标的元素相等(元素本应该在的位置),则说明这个元素重复了
if(numbers[i] == numbers[numbers[i]]){
//把这个重复的元素存储在duplication[]数组中
duplication[0] = numbers[i];
return true;
}else{ //若不相等,即交换,把元素放到与下标对应的位置
int temp = numbers[i];
numbers[i] = numbers[temp];
numbers[temp] = temp;
}
}
}
return false;
}
加入Scanner:
import java.util.Scanner;
public class Test {
public static void getRepeateNum( int[] num) {
int NumChange;
System.out.println("重复数字是:");
for(int index = 0; index < num.length; index++) {
while(num[index] != index) {
if(num[index] == num[num[index]]) {
System.out.print(num[index]+" ");
break;
} else {
NumChange = num[num[index]];
num[num[index]] = num[index];
num[index] = NumChange;
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] num = new int[5]; //数组长度可以自己定义
System.out.println("请输入一组数据:");
for(int i = 0; i < 5; i++) {
num[i] = scanner.nextInt();
}
getRepeateNum(num);
}
}
2.二维数组中的查找
题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
Consider the following 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]
]
Given target = 5, return true.
Given target = 20, return false.
解题思路: 选择从左下角开始搜寻,因为选择在左下角搜寻的话,如果目标值大于搜索值,那么就向右继续搜索,如果目标值小于搜索值,那么就向上继续搜索。可以根据target和当前元素的大小关系来缩小查找区间
public class Test {
public boolean Find(int target, int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
return false;}
int rows = matrix.length;//定义多维数组的行数
cols = matrix[0].length;//定义多维数组的列数
int r = 0, c = cols - 1; //从右上角开始
while (r <= rows - 1 && c >= 0) {
if (target == matrix[r][c]){
return true;
}else if (target > matrix[r][c]){
r++;
}else{
c--;
}
return false;
}
public static void main(String[] args) {
Test test=new Test();
int[][] matrix={{1,2,3},{4,5,6},{7,8,9}};//测试一个三行三列的数组,目标值为5
System.out.println(test.Find(matrix, 5));
}
}
二维数组的声明:
type[][] 数组名=new type[行元素个数][列元素个数];
声明同时赋值:
int[][] matrix={{1,2,3},{4,5,6},{7,8,9}};
二维数组的length()方法:
在二维数组中:
数组名.length表示数组的行数
数组名[行下标] .length表示该行中的元素个数
11.旋转数组的最小数字
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1
解题思路1:从头到尾遍历数组一次,找出最小的元素
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0){
return 0;
}
int ans=array[0];
for(int i=1;i<array.length;i++){
ans=Math.min(ans,array[i]);
}
return ans;
}
}
Math中的min方法是用来比较两个数大小的,返回较小的那个数值
用法:Math.min(a, b);
解题思路2:旋转数组实际上可以划分为两个有序的子数组,最小的元素刚好是这两个字数组的分界线,故旋转数组找最小元素值也可以采取二分查找的思路。通过二分查找,不断更新存在于两个非递减的排序子数组的下标
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0){
return 0;
}
int left=0;
int right=array.length-1;
while(left<right-1){
int mid=(left+right)/2;
if(array[left]<=array[mid]){
left=mid; //说明mid所在位置是在第一个非递减子数组中
}else if(array[right]>=array[mid]){
right=mid; //说明mid所在位置是在第二个非递减子数组中
}
}return array[right];
}
}