- 读清题目很关键,长度为n的数组,范围在0~n-1。
- 开额外数组设置标记的做法真的很low。
书上的思想真的很nice,时间O(n) 空间O(1)
public class Solution { public boolean duplicate(int numbers[], int length, int[] duplication) { if (length <= 0 || numbers == null) { return false; } int index = 0; while (index < length) { if (numbers[index] == index) { // 当前下标index的值刚好为index index++; } else { int tmp = numbers[index]; if (tmp == numbers[tmp]) { // 要交换位置的两个数相同 duplication[0] = tmp; return true; } else { // 交换位置 numbers[index] = numbers[tmp]; numbers[tmp] = tmp; } } } return false; } }
讨论区BoTinker的思想,在原数组上通过+length的方式达到开标记数组的目的,思想很赞!!! 时间O(n) 空间O(1)
public class Solution { public boolean duplicate(int numbers[], int length, int[] duplication) { if (length <= 0 || numbers == null) { return false; } for (int i = 0; i < length; i++) { int index = numbers[i]; if (index >= length) { index -= length; } if (numbers[index] >= length) { duplication[0] = index; return true; } numbers[index] += length; } return false; } }