面试编程题

来源:互联网 发布:sql server下载安装 编辑:程序博客网 时间:2024/06/06 01:35

1 生成子集

1.1 含义

给定一个集合,枚举它所有可能的子集。

比如给定集合{1,2,3},应该输出:

{}

{1}

{2}

{1, 2}

{3}

{1, 3}

{2, 3}

{1, 2, 3}

1.2 增量构造法

增量构造法,每次选择一个元素放到集合中,每次操作的结果即是一个子集。

递归操作,每次向当前集合中添加一个比当前集合中最大的元素大1的数。

代码:

[python] view plain copy
  1. from __future__ import print_function  
  2.   
  3. def print_subset(n, lst, cur):  
  4.     for i in range(cur):  
  5.         print(lst[i]+1, end='')  
  6.     print()  
  7.     if cur:  
  8.         s = lst[cur - 1] + 1  
  9.     else:  
  10.         s = 0  
  11.     for i in range(s, n):  
  12.         lst[cur] = i  
  13.         print_subset1(n, lst, cur+1)  

1.3 位向量法

构造位向量(可理解为构造一个数组),该向量中的每一位置可以取0值或者1值,0和1分别代表该位置上对应的值是否在集合中。如向量为[1, 0, 0, 1],其第1和4位上有1,所以该向量表示的集合为{1, 4}。

思路:
如果需要用向量来表示集合,那么需要保证向量的每一种变化能够刚好覆盖集合的每一种可能性。

对n求子集,构造长度为n的向量,每一位可以代表取或者不取该位置的值,共有2^n中可能。

代码为:
[python] view plain copy
  1. from __future__ import print_function  
  2.   
  3. def print_subset(n, lst, cur):  
  4.     if cur == n:  
  5.         for i in range(n):  
  6.             if lst[i]:  
  7.                 print(i+1, end='')  
  8.         print()  
  9.     else:  
  10.         lst[cur] = 0  
  11.         print_subset(n, lst, cur+1)  
  12.         lst[cur] = 1  
  13.         print_subset(n, lst, cur+1)  

1.4 二进制法

我们可以使用二进制法来表示子集。对于n求子集,其子集有2^n个(包括空集),比如n = 4,其有16个子集,这16个子集用二进制可以表示成:

0->0000->{}
1->0001->{1}
2->0010->{2}
3->0011->{1,2}
4->0100->{3}
5->0101->{1,3}
...

15->1111->{1,2,3,4}

思路:

求n的子集,可以依次处理1到2^n - 1之间的每一个数,每个数取出它二进制表示中的1的位置,以此表示该数对应的集合。比如5,二进制表示的后四位为0101,其在第1和第3位处有1,那么,其代表的集合为{1, 3}。使用位运算中与(&)操作,可以方便的求出二进制某位置上是否为1。

代码:
[python] view plain copy
  1. from __future__ import print_function  
  2. s = 1  
  3. n = 4  
  4. while s < (1 << n):  # 依次遍历1到2^n - 1之间的每一个数  
  5.     for i in range(n):  # 每一个数使用&操作判断该位置上是否有1,有打印或者保存起来  
  6.         if s & (1 << i):  
  7.             print(i+1, end='')  
  8.     print()  
  9.     s += 1  
原创粉丝点击