
二、解题思路
- 既然所有数字都在 [ 0 , n − 1 ) [0, n-1) [0,n−1)范围内,那么一个下标一定对应着一个值,且该值与下标最终一定相等,一个萝呗占一个坑。
- 如果比较过程中,下标和值不等,那么就交换理论上与值唯一匹配的那个下标的值( a [ a [ i ] ] a[a[i]] a[a[i]])和当前的值( a [ i ] a[i] a[i]),不停地交换,直到它们相等。
- 如果在这一过程中(下标和值此时仍然不匹配),理论上与值唯一匹配的那个下标的值 a [ a [ i ] ] a[a[i]] a[a[i]])和当前的值( a [ i ] a[i] a[i])相等,那说明遇到了两个相等的值,于是直接返回
- 默认返回 − 1 -1 −1
三、解题代码
class Solution {
public:
int findRepeatNumber(vector<int>& a) {
auto len = a.size();
for(size_t i = 0; i < len; i++){
while(a[i] != i){
if(a[i] == a[a[i]])
return a[i];
swap(a[i], a[a[i]]);
}
}
return -1;
}
};
四、测试程序
#include <cstdio>
bool duplicate(int numbers[], int length, int *duplication)
{
if (length <= 0 || numbers == nullptr)
return false;
for (int i = 0; i < length; i++)
{
if (numbers[i] < 0 || numbers[i] > length - 1)
return false;
}
for (int i = 0; i < length; ++i)
{
while (numbers[i] != i)
{
if (numbers[i] == numbers[numbers[i]])
{
*duplication = numbers[i];
return true;
}
auto tmp = numbers[i];
numbers[i] = numbers[tmp];
numbers[tmp] = tmp;
}
}
return false;
}
bool contains(int array[], int length, int number)
{
for (int i = 0; i < length; ++i)
{
if (array[i] == number)
return true;
}
return false;
}
void test(char *testName, int numbers[], int lengthNumbers, int expected[], int expectedExpected, bool validArgument)
{
printf("%s begins: ", testName);
int duplication;
bool validInput = duplicate(numbers, lengthNumbers, &duplication);
if (validArgument == validInput)
{
if (validArgument)
{
if (contains(expected, expectedExpected, duplication))
printf("Passed.\n");
else
printf("FAILED.\n");
}
else
printf("Passed.\n");
}
else
printf("FAILED.\n");
}
void test1()
{
int numbers[] = {
2, 1, 3, 1, 4};
int duplications[] = {
1};
test("Test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
}
void test2()
{
int numbers[] = {
2, 4, 3, 1, 4};
int duplications[] = {
4};
test("Test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
}
void test3()
{
int numbers[] = {
2, 4, 2, 1, 4};
int duplications[] = {
2, 4};
test("Test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
}
void test4()
{
int numbers[] = {
2, 1, 3, 0, 4};
int duplications[] = {
-1};
test("Test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
}
void test5()
{
int numbers[] = {
2, 1, 3, 5, 4};
int duplications[] = {
-1};
test("Test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
}
void test6()
{
int *numbers = nullptr;
int duplications[] = {
-1};
test("Test6", numbers, 0, duplications, sizeof(duplications) / sizeof(int), false);
}
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
return 0;
}
五、运行结果
main.cpp: In function 'void test1()':
main.cpp:126:113: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
^
main.cpp: In function 'void test2()':
main.cpp:134:113: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
^
main.cpp: In function 'void test3()':
main.cpp:142:113: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
^
main.cpp: In function 'void test4()':
main.cpp:150:114: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
^
main.cpp: In function 'void test5()':
main.cpp:158:114: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
^
main.cpp: In function 'void test6()':
main.cpp:166:86: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
test("Test6", numbers, 0, duplications, sizeof(duplications) / sizeof(int), false);
^
Test1 begins: Passed.
Test2 begins: Passed.
Test3 begins: Passed.
Test4 begins: Passed.
Test5 begins: Passed.
Test6 begins: Passed.
