设计算法以判断集合A是否是集合B的子集 (顺序表 链表)

需要注意的是 :在CSDN某些博文中,有很多博主把判断子集的代码写成了判断连续子序列的代码,我认为这是不对的。因为连续子序列和子集有着明显的区别,连续子序列一定是子集,但子集不一定是连续子序列。
子序列和子集之间也有着区别。
因此大家写代码时要注意一点,
这是比较好的 思路算法
见:https://blog.csdn.net/qq_39189509/article/details/78158277
但在考场上使用这种暴力的算法更加简单易行:

Bool subset(LinkList la, LinkList lb) { 
 LinkNode * pa,*pb;   
 pa=la->next;   
 while(pa) 
  {  pb=lb->next; 
     while(pb&&(pb->data!=pa->data)) pb=pb->next;  
      if(!pb) return False;   
      pa=pa->next;  }   return True; 
}

算法时间复杂度O(A.Length*B.Length)
同样,顺序表思路一致:

Bool subset(Sqlist LA,Sqlist LB){
int i=0;
while(i<LA.length){
int j=0;
while(j<LB.length)
if(LB.data[j]!=LA.data[i]) j++;
if(j=LB.length) return Flase;
i++;
}
reture True;
}

需要注意的是,空集是任何集合的子集,因此可以添加一个条件判断A序列是否是空集。
对于评论区提出的集合A = {1, 2, 2},B = {1, 2, 3}。直接运行上述算法会返回True,但实际上A不是B的子集。
问题出在对重复元素的处理上。这两种算法都没有考虑到集合中可能存在重复元素的情况。
为了解决这个问题,需要在内层循环中增加一点逻辑:
对于链表:

Bool subset(LinkList la, LinkList lb) {
  LinkNode *pa, *pb;
  pa = la->next; 
  while(pa) {
    pb = lb->next;
    while(pb && pb->data != pa->data) {
      if(pb->data == pa->data) break; // 增加判断逻辑
      pb = pb->next; 
    }
    if(!pb) return False;
    pa = pa->next;  
  }
  return True;
}

对于顺序表:

Bool subset(Sqlist la, Sqlist lb) {
  int i = 0;
  while(i < la.length) {
    int j = 0;
    while(j < lb.length) {
      if(lb.data[j] == la.data[i]) break; // 增加判断逻辑  
      j++;
    }
    if(j == lb.length) return False;
    i++;
  }
  return True;
}

增加了判断重复元素的逻辑后,就可以正确处理包含重复元素的集合情况了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值