448. Find All Numbers Disappeared in an Array 2

来源:互联网 发布:网络推广考核标准 编辑:程序博客网 时间:2024/06/03 16:00

这是一个空间复杂度为O(1),时间复杂度为O(n)的解法。

原题

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:

Input:[4,3,2,7,8,2,3,1]Output:[5,6]

题目分析

这个题算法有个技巧,注意观察索引和元素值的关系,如下表所示,如果1~5所有的元素都出现一次,那么如何标记只出现一次呢?通过a[0] = 5 ; a[5-1]得到1,标记为a[4] = -1;a[4]标记为负数后,即证明了元素5的存在。 相对的,映射后如果a[i]为正数,表明 i+1不存在!
根据映射关系 a[Abs(a[i])-1],a[1] = 3; a[3-1] = 2, 标记为a[2] = -2,这样所有的元素都标记为了负数,证明只出现了一次。

索引 值 映射后 0 5 -5 1 3 -3 2 2 -2 3 4 -4 4 1 -1

如果元素出现重复,如下表,根据映射关系 a[Abs(a[i])-1]

索引 值 映射后 0 2 -2 1 3 -3 2 2 -2 3 3 3 4 1 1

根据上述映射关系,a[0] = 2; a[2-1] = -3; a[1] =3; a[3-1]=-2; 标记a[2] = 2; a[1] = -3 此时注意,如果a[i]<0,我们不再标记为相反数。a[3] = 3; a[2] = -2; 不再标记a[4] = 1; a[0] = -2; 标记

可以看出索引 3, 4的值大于0,缺失的元素正是 4,5

代码实现

 public IList<int> FindDisappearedNumbers2(int[] nums)        {            IList<int> rtn = new List<int>();            for (int i = 0; i < nums.Length; i++)            {                int index = Math.Abs(nums[i]) - 1;                if (nums[index] > 0)                    nums[index] = -nums[index];            }            for (int i = 0; i < nums.Length; i++)            {                if(nums[i]>0)                    rtn.Add(i+1);            }            return rtn;        }
2 0
原创粉丝点击