题目一

    1. import java.util.Arrays;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. public class Array3 {
    5. /**
    6. * 面试题3:数组中重复的数字
    7. * 题目一:找出数组中重复的数字。在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的。请找出数组中任意一个重复的数字
    8. * 例如:如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复数字2或者3
    9. */
    10. public static void main(String[] args) {
    11. //测试用例的选择
    12. //正常数组{2,3,1,0,2,5,3}
    13. //不正常数组{2,4,1,0}
    14. //无效数组{},{9,9}
    15. int[] test1 = {2, 3, 1, 0, 2, 5, 3};
    16. int[] test2 = {2, 3, 1, 0};
    17. int[] test3 = {};
    18. int[] test4 = {9, 9};
    19. System.out.println(function4(test1));
    20. System.out.println(function4(test2));
    21. System.out.println(function4(test3));
    22. System.out.println(function4(test4));
    23. }
    24. //暴力解法
    25. private static int function1(int[] array1) {
    26. int length = array1.length;
    27. if (length <= 1) {
    28. return 0;
    29. }
    30. for (int j : array1) {
    31. if (j > length) {
    32. return 0;
    33. }
    34. }
    35. for (int i = 0; i < length; i++) {
    36. for (int j = i + 1; j < length; j++) {
    37. if (array1[i] == array1[j]) {
    38. return array1[i];
    39. }
    40. }
    41. }
    42. return 0;
    43. }
    44. //先排序,后暴力
    45. private static int function2(int[] array2){
    46. if(array2.length<=1||array2[array2.length-1]>array2.length){
    47. return 0;
    48. }
    49. Arrays.sort(array2);
    50. for(int i = 0; i< array2.length - 1;i++){
    51. if (array2[i]==array2[i+1]){
    52. return array2[i];
    53. }
    54. }
    55. return 0;
    56. }
    57. //哈希实现
    58. private static int function3(int[] array3){
    59. int length = array3.length;
    60. if (length <= 1) {
    61. return 0;
    62. }
    63. for (int j : array3) {
    64. if (j > length) {
    65. return 0;
    66. }
    67. }
    68. HashMap<Integer, Integer> check = new HashMap<Integer,Integer>();
    69. for (int i : array3){
    70. if(check.containsKey(i)){
    71. return i;
    72. }else{
    73. check.put(i,1);
    74. }
    75. }
    76. return 0;
    77. }
    78. //O(1)复杂度的实现
    79. private static int function4(int[] array4){
    80. int length = array4.length;
    81. if (length <= 1) {
    82. return 0;
    83. }
    84. for (int j : array4) {
    85. if (j > length) {
    86. return 0;
    87. }
    88. }
    89. for (int i = 0; i < array4.length; i++) {
    90. if(array4[i]!=i){
    91. if(array4[i]==array4[array4[i]]){
    92. return array4[i];
    93. }else{
    94. //这里要注意先令temp = array4[array4[i]],否则,再第三行赋值的时候会出问题
    95. int temp = array4[array4[i]];
    96. array4[array4[i]] = array4[i];
    97. array4[i] = temp;
    98. i--;
    99. }
    100. }
    101. }
    102. return 0;
    103. }
    104. }

    题目二

    /**
     * 面试题3:数组中重复的数字
     * 题目二:不修改数组找到重复的数字
     * 在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。找出数组中任意一个重复的数字,但不能修改输入的数组
     * 例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7}那么对应的输出是重复的数字2或者3
     */
    public class Array3_2 {
        public static void main(String[] args) {
            //测试用例的选择
            //正常数组{2,3,1,0,2,5,3}
            //不正常数组{2,4,1,0}
            //无效数组{},{9,9}
            int[] test1 = {2, 3, 1, 0, 2, 5, 3};
            int[] test2 = {2, 3, 1, 0};
            int[] test3 = {};
            int[] test4 = {9, 9};
            System.out.println(function2(test1));
            System.out.println(function2(test2));
            System.out.println(function2(test3));
            System.out.println(function2(test4));
        }
        //辅助数组
        private static int function1(int[] array1){
            if(array1.length<=1){
                return 0;
            }
            int[] arrayClone = new int[array1.length];
            for (int j : array1) {
                if(j>array1.length){
                    return 0;
                }
                if (arrayClone[j] != 0) {
                    return j;
                } else {
                    arrayClone[j] = j;
                }
            }
            return 0;
        }
    
        //二分查找思想
        private static int function2(int[] arr){
            int low = 1;
            int high = arr.length - 1; // high即为题目的n
            int mid, count;
            while (low <= high) {
                mid = ((high - low) >> 2) + low;
                count = countRange(arr, low, mid);
                if (low == high) {
                    if (count > 1)
                        return low;
                    else
                        break;
                }
                //判断条件的选取要慎之又慎
                if (count > mid - low + 1) {
                    high = mid;
                } else {
                    low = mid + 1;
                }
            }
            return -1;
        }
    
        /**
         * 返回在[low,high]范围中数字的个数
         */
        public static int countRange(int[] arr, int low, int high) {
            if (arr == null)
                return 0;
    
            int count = 0;
            for (int a : arr) {
                if (a >= low && a <= high)
                    count++;
            }
            return count;
        }
    
    }