Redis

252 阅读4分钟

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];
    }
}