论坛首页 Java企业应用论坛

一道笔试题(创新工厂)

浏览 33275 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
作者 正文
   发表时间:2010-10-21  
zhongkem 写道

有两个长度分别为m,n的非递减整型数组,其中n>m*m,求这两个数组的交集,要求复杂度尽可能低

 

如数组a:-1,4,5

数组b:-15,1,3,4,5,7,8,9,10,15

结果应该是:4,5

 

题目大概就是这样,欢迎大家练手,并把结果发上来讨论,我也会尽快贴上我的代码~~

 

可以先分别遍历一次两数组,把两个数组先分组,类似桶式排序的方式。

 

然后按分组比较,减少比较次数

0 请登录后投票
   发表时间:2010-10-21  
最简单的方法,创建一个新数组c,长度为a,b之和。
将长度为N的数组,假设为b,全部填充到c中,
然后将长度为m的数组a的元素,逐个填充到b中,
填充时判断当前值是否已经存在,若存在,说明属于a b 交集元素,
将此元素放入长度为m的数组d中。

最复杂度:M+N次。即没有交集。

另外:个人觉得 排序、List、Set方式,本身已经增加了复杂度。

注:此方法没有考虑数组的顺序性。
0 请登录后投票
   发表时间:2010-10-21   最后修改:2010-10-21
fuliang 写道
二分查找。
无论指针移动类似的归并方法,还是使用hashset,复杂度都是n+m > m * m + m = m(m+1) = O(m^2)。
使用二分查找,从小的集合中的元素依次二分查找大集合,得到公共元素的复杂度为:
m * logn = m* log(m^2) = 2m * logm = O(m*logm)

每次二分查找后,把查找的结果的index,返回给下一次查找,作为下次数组查找的起始位置,这样每次查找的范围都会变小

def common_element(a,b)
  ce = []
  last_mid = 0
  a,b = b,a if a.size > b.size
  a.each do |i|
    mid = binary_search(i,b,last_mid)
    if i == b[mid]
      ce << i
      last_mid = mid
    end
    p last_mid
  end
end

def binary_search(i,b,last_mid)
  s1 = last_mid
  s2 = (b.size) -1
  mid = (s1+s2)/2
  while(s1 < s2 && b[mid] != i)
    s1 = mid+1 if b[mid] < i
    s2 = mid-1 if b[mid] > i
    mid = (s1+s2)/2
  end
  mid
end

m = [-1,4,5]
n = [-15,1,3,4,5,7,8,9,10,15]
result = common_element(m,n)
p result.join('  ')

结果
引用
0
3
4
"-1  4  5"


phyeas 写道
如果数组元素不重复并且已排序。最好的办法应该是初始化俩指针遍历两个数组的方法(参考IR导论前面几章中提到的求交集的方法),具体做法是:
先初始化两个指针分别指向数组的开始。
比较当前指针指向的俩个元素,如果指针2的元素大于指针1,则移动指针1,如果指针1指向的元素大于指针2,则移动指针2,如果相等则保存结果然后俩指针同时向前移动。如此重复到读取完两个数组的元素。此方法需要遍历两个数组,用Set方法需要遍历两个数组而且需要对元素做hash运算+比较,效率没有上诉算法快。
但本题中有一个关键词是“非递减”。不知道在这里是甚么意思,望LZ告知


这种方法的效率应该没有二分高吧?m+n比较mlogn.
m+n/mlogn化简后(1+n/m)/logn.约等于n/mlogn.因为n>m*m所以n/mlogn>m/logn>m/2logm.明显m/2logm,在m>2的情况下都是大于1的.
0 请登录后投票
   发表时间:2010-10-21  
感觉题目不是很明确,没说是否重复,和是否是递增型的

给出的例子来说,二分应该不错,最好在每次查找完再截去比它小的元素
0 请登录后投票
   发表时间:2010-10-21   最后修改:2010-10-21
幽灵线程 写道
最简单的方法,创建一个新数组c,长度为a,b之和。
将长度为N的数组,假设为b,全部填充到c中,
然后将长度为m的数组a的元素,逐个填充到b中,
填充时判断当前值是否已经存在,若存在,说明属于a b 交集元素,
将此元素放入长度为m的数组d中。

最复杂度:M+N次。即没有交集。

另外:个人觉得 排序、List、Set方式,本身已经增加了复杂度。

注:此方法没有考虑数组的顺序性。

你这个的意思不是遍历么?而且不考虑顺序,复杂度也不是M+N.而是M*N.
0 请登录后投票
   发表时间:2010-10-21  
数字会不会很多?
将数组a插入a表
将数组b插入b表
select * from a
intersect
select * from b
哈哈,会不会复杂度很高? 

复杂度高不高我不知道 ,只知道工作量比较大
0 请登录后投票
   发表时间:2010-10-21  
public static void main(String[] args)
    {
        int[] b = { -1, 4, 5 };
       
        int[] a = { -15, 1, 3, 4, 5, 7, 8, 9, 10, 15, 300 };
       
        int aindex = 0;
       
        int bindex = 0;
       
        while (aindex < a.length && bindex < b.length)
        {
            if (a[aindex] == b[bindex])
            {
                System.out.println(a[aindex]);
               
                aindex++;
                bindex++;
               
                continue;
            }
           
            if (a[aindex] < b[bindex])
            {
                aindex++;
                continue;
            }
           
            if (a[aindex] > b[bindex])
            {
                bindex++;
                continue;
            }
        }
    }
0 请登录后投票
   发表时间:2010-10-21  

  我也发一个:

public class IntersectionCalc {

	public static void main(String[] args) {
		int[] a = { -1, 4, 5, 5 };
		int[] b = { -15, 1, 3, 4, 5, 5, 7, 8, 9, 10, 15 };

		int i = 0, j = 0;
		Integer preValue = null;
		while (i < a.length && j < b.length) {
			if (a[i] < b[j]) {
				i++;
			} else if (a[i] > b[j]) {
				j++;
			} else {
				if (preValue == null || preValue != a[i]) {
					preValue = a[i];
					System.out.print(a[i] + ", ");
				}
				i++;
				j++;
			}
		}

	}

}
 
0 请登录后投票
   发表时间:2010-10-21  

  创新工厂就考这么简单的笔试题吗

0 请登录后投票
   发表时间:2010-10-21  

  我等老抛来发话

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics