正负号标记法在数组相关程序中的使用
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
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
相关文章推荐
- 编写一个使用数组类模板Array对数组进行排序、求最大值和求元素和的程序,并采用相关数据进行测试。
- 编写一个使用数组类模板Array对数组进行排序、求最大值和求元素和的程序,并采用相关数据进行测试。
- smartdrv.exe的使用及简单说明和相关程序下载
- 1、将数组中的元素再定义为特殊的名字方便程序中使用
- Rotated array related program. 和旋转数组相关的几个程序
- 实验 8 数组2 1、程序调试,按照“分析结果、设置断点、使用单步执行并观察变量、分析变量结果、修改程序”五个阶段调试和改正程序;
- 使用JavaScript完成一个对字符串数组进行排序的小程序
- 使用静态数组让程序“跑”的更快
- VC关于使用了相关控件的程序出现:该内存不能为read的解决办法
- Android定义字符串数组资源并在程序中使用
- 打印不同的数(编写一个程序,使用指针访问数组方式,读入十个数,输出其中不同的数,即一个数如果出现多次,只打印一次)
- NET简单的一个画图程序 使用简单 自己可以相关自己的内容进行配置就可以使用了
- 【EntityFramework系列教程六,翻译】在ASP.NET MVC程序中使用EntityFramework对相关数据进行更新
- 编写一个程序读入一行输入,然后反向打印该行,您可以把输入存储在一个char数组中: 假定该行不超过255个字符。回忆一下,您可以使用具有%c说明符的scanf()从输入中一次 读入一个字符,而且当您按下回车键时会产生换行符(/n)
- 在一个方法里生成了一个自动释放的数组,在另一个方法里使用它会导致程序崩溃。
- 编写一个程序读入一行输入,然后反向打印该行,您可以把输入存储在一个char数组中: 假定该行不超过255个字符。回忆一下,您可以使用具有%c说明符的scanf()从输入中一次 读入一个字符,而且当您按
- 一些linux应用小技巧,网络相关,系统管理,shell,程序使用
- 微软MSDN给出的使用.Net开发Windows Form网络应用相关程序的优化建议
- 使用java程序读取配置文件中的相关属性值-asp.net关注
- 编写程序,使用指针把一个int型数组的所有元素设置为0