# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第4章 数组 4.1_2 如何找出数组中重复元素序列
题目:
对于一个给定的自然数N,有一个N+M个元素的数组,其中存放了小于等于N的所有
自然数,求重复出现的自然数序列[X]
分析:
关键:
1 书上解法
采用这种形式: array[ array[index] ]的形式
判断某个元素是否重复就用: 每次访问完某个元素后,
就令该元素为 该元素乘以-1,下次碰到某个元素如果值是
负数表示已经访问过。
遇到重复数字修改为靠近N+M的自然数。
2 没想到
是因为没想到可以让元素变成其相反数来判断是否重复;
没想到用array[array[index]]的形式,并设置重复元素
为靠近N+M的自然数
参考:
Python程序员面试算法宝典
'''
def findRepeatedElements(array, num):
if not array:
return
index = array[0]
length = len(array)
remainder = length - num
result = set()
while True:
# 遇到重复元素,将该重复元素修改为接近N+M的元素
if array[index] < 0:
remainder -= 1
array[index] = length - remainder
# 能使得array[index]出现重复时,其下标(实际也是数组的一个元素)必定是重复的
# 否则不会重复出现array[index],因此这里添加的是index而不是array[index]
result.add(index)
# 如果剩余重复元素为0了,说明全部遍历完成,直接返回
if remainder == 0:
return result
# 令当前元素 = 当前元素 * -1,用于后续判断该元素是否重复
array[index] *= -1
index = array[index] * (-1)
return result
def process():
array = list(range(1, 6)) + [3, 5, 3, 5, 2]
results = findRepeatedElements(array, 6)
print results
assert results == set([3, 5, 2])
if __name__ == "__main__":
process()