剑指 Offer 03. 数组中重复的数字

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3

  1. package com.coco.learnalgorithmone.array;
  2. import java.util.*;
  3. /**
  4. * 剑指 Offer 03. 数组中重复的数字
  5. * 找出数组中重复的数字。
  6. *
  7. *
  8. * 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
  9. * 数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。
  10. * 请找出数组中任意一个重复的数字。
  11. */
  12. public class FindRepeatNumber {
  13. public static void main(String[] args) {
  14. int[] nums = {2, 3, 1, 0, 2, 5, 3};
  15. System.out.println(findRepeatNumber1(nums));
  16. System.out.println(findRepeatNumber2(nums));
  17. System.out.println(findRepeatNumber3(nums));
  18. System.out.println(findRepeatNumber4(nums));
  19. }
  20. public static int findRepeatNumber1(int[] nums) {
  21. Set<Integer> numSet = new HashSet<>();
  22. for (int num : nums) {
  23. if (numSet.contains(num)) {
  24. return num;
  25. }
  26. numSet.add(num);
  27. }
  28. return -1;
  29. }
  30. public static int findRepeatNumber2(int[] nums) {
  31. Arrays.sort(nums);
  32. for (int i = 1; i < nums.length; i++) {
  33. if (nums[i] == nums[i - 1]) {
  34. return nums[i];
  35. }
  36. }
  37. return -1;
  38. }
  39. public static int findRepeatNumber3(int[] nums) {
  40. int[] tmp = new int[nums.length];
  41. for (int num : nums) {
  42. if (tmp[num] != 0) {
  43. return num;
  44. }
  45. tmp[num] = 1;
  46. }
  47. return -1;
  48. }
  49. public static int findRepeatNumber4(int[] nums) {
  50. for (int i = 0; i < nums.length; i++) {
  51. int num = nums[i];
  52. if (num != i) {
  53. int corr = nums[num];
  54. if (num == corr) {
  55. return num;
  56. }
  57. nums[i] = corr;
  58. nums[num] = num;
  59. --i;
  60. }
  61. }
  62. return -1;
  63. }
  64. }

findRepeatNumber1

思路:利用Set集合的特性,遍历数组,往集合中新增num,当新增的num已经存在Set集合中时,代表num重复出现。

findRepeatNumber2

思路:将数组从小到大排序,遍历数组,比较相邻的两个num,当相等时,代表num重复出现。

findRepeatNumber3

思路:根据题目得知数组中num的范围在[0, n-1]区间,由此创建一个与数组长度一致的临时数组,用于记录每一个索引上num的状态。
遍历数组,往临时数组的num索引上赋值1。若临时数组的num索引上的值不为0,则代表num重复出现。