求已知集合中某两个或三个元素之和等于确定值问题 收藏

本文介绍如何通过排序及双指针技巧,在O(NlogN)和O(N^2)的时间复杂度内,分别找出数组中是否存在两个或三个数之和等于特定值的有效算法。

求已知集合中某两个或三个元素之和等于确定值问题 收藏
问题描述:

1、给定一个数组,该数组包含N个元素。我们想要确定是否存在两个数它们的和等于给定的数K。例如,如果输入是8,4,1,6而K是10,则答案为yes(4和6)。一个数可以被使用两次。
给出求解该问题的O(NlogN)算法。

2、1、给定一个数组,该数组包含N个元素。我们想要确定是否存在三个数它们的和等于给定的数K。例如,如果输入是8,4,1,6而K是13,则答案为yes(8和4和1)。一个数可以被使用两次或三次。
给出求解该问题的O(N2)算法。

解题思路:

1,首先用快速排序或并归排序将已知集合排序(nlogn),然后用类似于快速排序的方法操作,代码如下:

//L是已经排序好的数组

bool f( int *L, int len, int sum ){
int i=0, j=len-1;
while( i<j ){ if( L[i]+L[j]==sum )
return true;
else
if( L[i]+L[j]>sum )
--j;
else
++i;
}
return false;
}
2,先将数组按递增进行快速排序,快速排序的复杂度是O(nlogn)的。
还是用问题1的方法,我们从问题1的解决方法中可以看到:
如果数组是有序的,那么确定是否存在两个数它们的和等于给定的数sum的算法的时间复杂度是O(n)的(n为数组长度)。

现在,我们要找确定是否存在L[i]+L[j]+L[k]=sum。 (1)
不妨令L[i] <=L[j] <=L[k]
我们现在将(1)式变为: L[i]+L[j]=sum-L[k]
令SUM=sum-L[k]。
现在,容易看到SUM的值只可能有n个,而对每一个SUM,我们确定是否存在两个数它们的和等于给定的数SUM的时间复杂度是O(n)的,于是,总的时间复杂度是:
O(nlogn+n^2)=O(n^2)。

http://topic.youkuaiyun.com/u/20080314/21/7fff8e74-ed62-4d34-90c9-8d4e05bc52a4.html

对于已知两个链表AB分别表示两个集合的情况,可进行交集、并集、差集等操作。 ### 并集操作 开拓三个空间的链表,一个存放集合A元素,一个存放集合B元素,然后一个存放删去AB集合中重复元素剩下的所有元素。不过该方法会浪费一定的空间[^1]。 ### 交集操作 难点在于交集运算,目前引用未提及具体解决方案,但可以通过遍历链表AB,找出同时存在于两个链表中的元素,将这些元素添加到一个新链表中,此新链表即为交集。 ### 差集操作 差集运算也是难点,引用未给出具体方案。A - B的差集时,可以遍历链表A,对于A中的每个元素,检查其是否存在于链表B中,若不存在则将其添加到一个新链表中,该新链表即为A - B的差集;B - A的差集同理。 ### 代码示例 以下为简单的Python代码示例,用于说明链表的基本操作及集合运算: ```python # 定义链表节点类 class Node: def __init__(self, data): self.data = data self.next = None # 定义链表类 class LinkedList: def __init__(self): self.head = None # 插入元素 def insert(self, data): new_node = Node(data) if not self.head: self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node # 检查元素是否存在于链表中 def contains(self, data): current = self.head while current: if current.data == data: return True current = current.next return False # 并集 def union(self, other): result = LinkedList() current = self.head while current: result.insert(current.data) current = current.next current = other.head while current: if not result.contains(current.data): result.insert(current.data) current = current.next return result # 交集 def intersection(self, other): result = LinkedList() current = self.head while current: if other.contains(current.data): result.insert(current.data) current = current.next return result # 差集(self - other) def difference(self, other): result = LinkedList() current = self.head while current: if not other.contains(current.data): result.insert(current.data) current = current.next return result # 创建链表AB A = LinkedList() A.insert(1) A.insert(2) A.insert(3) B = LinkedList() B.insert(3) B.insert(4) B.insert(5) # 并集 union_result = A.union(B) # 交集 intersection_result = A.intersection(B) # 差集 difference_result = A.difference(B) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值