剑指offer_3_数组中重复的数字

从今天开始刷算法题,先刷完剑指offer再说吧

题目描述

在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重 复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

Input:
{2, 3, 1, 0, 2, 5}
Output:
2

第一眼看到题,就只想到了暴力循环的方法。

 1 public class Solution {
 2     // Parameters:
 3     //    numbers:     an array of integers
 4     //    length:      the length of array numbers
 5     //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
 6     //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
 7     //    这里要特别注意~返回任意重复的一个,赋值duplication[0]
 8     // Return value:       true if the input is valid, and there are some duplications in the array number
 9     //                     otherwise false
10     public boolean duplicate(int numbers[],int length,int [] duplication) {
11     for(int i=0; i<length; i++){
12         for(int j=i+1;j<length;j++){
13             if(numbers[i]==numbers[j]){
14                 duplication[0]=numbers[j];
15                 return true;
16             }
17         }
18     }
19         return false;
20     }
21 }

然后我就去搜索了别人的解法,肯定有更好的方法。

解题思路:

对于这种数组元素在0-n-1的范围内的问题,可以将值为i的元素调整到第i个位置上求解。

 1 public boolean duplicate(int[] nums, int length, int[] duplication) {
 2 if (nums == null || length <= 0)
 3 return false;
 4 for (int i = 0; i < length; i++) {
 5 while (nums[i] != i) {
 6 if (nums[i] == nums[nums[i]]) {
 7 duplication[0] = nums[i];
 8 return true;
 9 }
10 swap(nums, i, nums[i]);
11 }
12 }
13 return false;
14 }
15 private void swap(int[] nums, int i, int j) {
16 int t = nums[i];
17 nums[i] = nums[j];
18 nums[j] = t;
19 }

本来我想把swap函数直接写进duplicate里面的时候又犯错了。哎。

因为我写的是

1 int t = nums[i];
2 nums[i] = nums[nums[i]];
3 nums[nums[i]] = t;

原因在于第三行的nums[nums[i]]已经不是我们想交换的数了,在第二行的时候nums[i]已经变了。

稍微改一下即可

1 int t = nums[i];
2 nums[i] = nums[nums[i]];
3 nums[t] = t;

不过,emmm这两个思路运行时间差不多倒是有点意外。

posted @ 2019-08-10 15:12  chyblogs  阅读(116)  评论(0)    收藏  举报