剑指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这两个思路运行时间差不多倒是有点意外。

浙公网安备 33010602011771号