您的位置:首页 > 其它

正负号标记法在数组相关程序中的使用

2016-11-20 22:26 183 查看
正负号标记法在一些关于数组的编程中往往能起到一些出其不意的效果,在这里我以几个示例来解释一下正负号标记法的用法。
1,我们看一下LeetCode的第448题。该题告知你一个有n个元素的数组,数组的所有元素介于1到n之间(包含1与n),但是 一些元素出现了两次,其他的元素都只出现一次,找出所有没有出现的数值。要求你不用额外的空间,并且在O(n)时间复杂度下解决该问题。你可以假设返回的列表不算在额外的元素中。
例如:
Input:
[4,3,2,7,8,2,3,1]

Output:
[5,6]我们再分析一下题目,给定的n个元素,每个元素都介于1到n,给出这个条件,首先想到的就是可否将数组中的元素与数组的下标对应起来?(这基本可以成为一个套路,当看到这种题目时,首先想到的就是将数组的元素与数组的下标对应起来)。我们用正负号标记法来解决这道题。首先我们遍历整个数组,当前元素为i,令nums[abs(i)-1]=-abs(nums[abs(i)-1]),即让每个元素所对应的下标的元素值变成一个负值。还以上面的例子来说,经过这个操作后数组变为:[-4, -3, -2, -7, 8, 2, -3, -1]。然后再次对数组进行遍历,将值为正数对应的下标加1即为求得结果。处理的后的数组有两个正值,分别为8,2,它们对应的下标为4和5,加1后变为5和6,则未出现的数值为[5, 6]。
我们用Python代码来实现上面的算法:
class Solution(object):
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
for i in nums:
nums[i-1] = -abs(nums[abs(i)-1])
return [i+1 for i, j in enumerate(nums) if j>0]
2,接下来我们再看一下leetcode的第442题。此题的题干与上题一样, 也是有一个n个元素的数组,数组的元素介于1到n之间(包含1到n),一些元素出现了一次,另一些元素出现了两次,让你找出所有出现了两次的元素。要求和上题一样,也是O(n)的空间复杂度,无额外的空间。
例如:
Input:
[4,3,2,7,8,2,3,1]

Output:
[2,3]与上题一样的思路,看到条件,首先想到的就是可否将数组中的元素与数组的下标对应起来。我们首先遍历数组,将元素值对应的下标所在的元素设为一个负值,比如让其乘以-1;如果在遍历的时候发现元素值对应下标的元素的值为负值,就说明该元素在之前出现过,即出现了两次。
我们用Python代码来实现上面的算法:
class Solution(object):
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
ans = []
for i in nums:
if nums[abs(i)-1]<0:
ans.append(abs(i))
else:
nums[abs(i)-1] *= -1
return ans
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐