代码改变世界

算法——数组和Hash(30%)

2012-12-18 15:10  msfte  阅读(1667)  评论(0编辑  收藏  举报

1,求子数组的最大和(数组)

分析

1)枚举:遍历每个子数组,比较并记录最大的

2)分治:从中间分开,有三种情况:(1)最大子数组在左边,(2)最大子数组在右边,(3)最大子数组包括中间的元素。T(n)=2T(n/2)+O(n): O(nlogn)

3)动态规划:(1)子结构:从开始到当前元素。(2)子结构Cache:1,内部最大值。2包含当前元素的最大值。(3)状态转移:1,如果前一个子结构的Cache2为负,当前则Cache2为当前元素,否则为前一元素Cache2加当前元素。2当前Cache1为当前Cache2和前一元素Cache1较大者。 O(n)

代码

1)枚举

        private int Enumeration(int[] array)
        {
            if (array == null || array.Length == 0)
                return -1;
            int? max = null;
            for (int i = 0; i < array.Length; i++)
            {
                int sum = 0;
                for (int j = i; j < array.Length; j++)
                {
                    sum += array[j];
                    if (max == null || sum > max)
                        max = sum;
                }
            }
            return max.Value;
        }

 2)分治

private int DivideAndConquer(int[] array)
        {
            if (array == null || array.Length == 0)
                return -1;
            return DivideAndConquerRecur(array, 0, array.Length - 1);
        }

        private int DivideAndConquerRecur(int[] array, int low, int high)//T(n):O(nlogn)
        {
            if (low >= high)
                return array[low];
            int max = array[low];
            int middle = low + (high - low) / 2;
            int left = DivideAndConquerRecur(array, low, middle - 1);//T(n/2)
            int right = DivideAndConquerRecur(array, middle + 1, high);//T(n/2)
            int middleMax = GetMiddleMax(array, low, high, middle);//O(n)
            return GetBigger(GetBigger(left, right), middleMax);
        }

        private int GetMiddleMax(int[] array, int low, int high, int middle)
        {
            int middleMax = array[middle];
            int middleSum = 0;
            for (int i = middle; i <= high; i++)
            {
                middleSum += array[middle];
                if (middleSum > middleMax)
                    middleMax = middleSum;
            }
            middleSum = 0;
            for (int i = middle; i >= low; i--)
            {
                middleSum += array[middle];
                if (middleSum > middleMax)
                    middleMax = middleSum;
            }
            return middleMax;
        }

        private int GetBigger(int first,int second)
        {
            return first > second ? first : second;
        }

 3)动态规划

        private int DynamicProgramming(int[] array)
        {
            int max = array[0];
            int maxUntil = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (maxUntil <= 0)
                    maxUntil = array[i];
                else
                    maxUntil = array[i] + maxUntil;
                if (maxUntil > max)
                    max = maxUntil;
            }
            return max;
        }

 

 

2,查找最小的k个元素(数组)

3, 假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在11000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?

4 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。 

要求时间复杂度是

O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。

例如输入数组12471115和数字15。由于4+11=15,因此输出411

5 n个数字(0,1,,n-1)形成一个圆圈,从数字0开始,

每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。

求出在这个圆圈中剩下的最后一个数字。

6, 输入两个整数

n m,从数列123.......n 中随意取几个数,

使其和等于

m ,要求将其中所有的可能组合列出来.

7, 有两个序列

a,b,大小都为n,序列元素的值任意整数,无序;

要求:通过交换

a,b中的元素,使[序列a元素的和][序列b元素的和]之间的差最小。

8,收藏了1万条url,现在给你一条url,如何找出相似的url。(面试官不解释何为相似)

9一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值

比如{32436} 可以分成{32436} m=1;

{3,6}{2,4,3} m=2 

{3,3}{2,4}{6} m=3 

所以m的最大值为3

10 求一个数组的最长递减子序列比如

{94325432}的最长递减子序列为{95432}

11, 一个数组是由一个递减数列左移若干位形成的,比如{432165}

是由{654321}左移两位形成的,在这种数组中查找某一个数。

12, 和为n连续正数序列(数组)。

题目:输入一个正数n,输出所有和为n连续正数序列。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-54-67-8

分析:这是网易的一道面试题。

13, 调整数组顺序使奇数位于偶数前面(数组)。

题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,

所有偶数位于数组的后半部分。要求时间复杂度为O(n)

14, 找出数组中两个只出现一次的数字(数组) 

15, 把数组排成最小的数(数组、算法)。

题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。

例如输入数组{32, 321},则输出这两个能排成的最小数字32132

请给出解决问题的算法,并证明该算法。

16, 旋转数组中的最小元素(数组、算法)。 

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。 

例如数组{3, 4, 5, 1, 2}{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1 

17 数组中超过出现次数超过一半的数字(数组) 

题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。

18 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i]其左边的数都小于等于它,右边的数都大于等于它。 

能否只用一个额外数组和少量其它空间实现。 

19, a~z包括大小写与0~9组成的N个数用最快的方式把其中重复的元素挑出来。

20 求随机数构成的数组中找到长度大于

=3的最长的等差数列9 d-x' W) w9 ?" o3 b0 R

输出等差数列由小到大:

如果没有符合条件的就输出

格式:

输入[1,3,0,5,-1,6]

输出[-1,1,3,5]

要求时间复杂度,空间复杂度尽量小

21, 用递归的方法判断整数组a[N]是不是升序排列

22,数组al[0,mid-1] 和 al[mid,num-1],都分别有序。将其merge成有序数组al[0,num-1],要求空间复杂度O(1)

23,求旋转数组的最小元素(把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1) 

24,有一个整数数组,求数组中第二大的数

25,对于给定的整数集合S,求出最大的d,使得a+b+c=d。a,b,c,d互不相同,且都属于S。集合的元素个数小于等于2000个,元素的取值范围在[-2^28,2^28 - 1],假定可用内存空间为100MB,硬盘使用空间无限大,试分析时间和空间复杂度,找出最快的解决方法。

26,给一个浮点数序列,取最大乘积子序列的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积子序列为3,0.5,8。

27,一个数组里,数都是两两出现的,但是有三个数是唯一出现的,找出这三个数。

28,给定一整型数组,若数组中某个下标值大的元素值小于某个下标值比它小的元素值,称这是一个反序。
即:数组a[]; 对于i < j 且 a[i] > a[j],则称这是一个反序。
给定一个数组,要求写一个函数,计算出这个数组里所有反序的个数。

29,有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列,对于1<=i,j<=k,求k个最小的(ai+bj),要求算法尽量高效。

30,有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。
31,一个N个元素的整形数组,如何找出前K个最大的元素

32,给定一数组,输出满足2a=b(a,b代表数组中的数)的数对

33,一个有序数组(从小到大排列),数组中的数据有正有负,求这个数组中的最小绝对值

34,有一个数组a,设有一个值n。在数组中找到两个元素a[i]和a[j],使得a[i]+a[j]等于n,求出所有满足以上条件的i和j。

35,1万个元素的数组,90%的元素都是1到100的数,10%的元素是101--10000的数,如何高效排序。

36,有序数组里二分查找一个数(如果有相同的找最后一次出现的)。
37,数组里找到和最接近于0的两个值。

38,对长度12的有序数组进行二分查找,目标等概率出现在数组的每个位置上,则平均比较次数为

39,一个文件有N个单词,每行一个,其中一个单词出现的次数大于N/2,怎么样才能快速找出这个单词

40,有一亿个数,输入一个数,找出与它编辑距离在3以内的书,比如输入6(0110),找出0010等数,数是32位的

41,一个文本,一万行,每行一个词,统计出现频率最高的前10个词(词的平均长度为Len)。并分析时间复杂度。

42,求数组中最长递增子序列

43,A[i]是一个有序递增数组,其中所有的数字都不相等,请设计一种算法,求出其中所有的A[i]=i的数字并分析时间复杂度,不分析复杂度不得分。

44,N个数组,每个数组中的元素都是递增的顺序,现在要找出这N个数组中的公共元素部分,如何做? 注:不能用额外辅助空间。 

45,降序排列的数组,找到其中两个不同的值,其乘积最接近一个给定的值M,感觉和加法求和很类似

46,序列123...N,N介于3和9之间,在其中加入+-或者空格,使其和为0,
如123456  1-2 3-4 5+6 7 等价于1-23-45+67=0。请问,如何获得所有组合?

47,判断两个数组中是否有相同的数字 

48,快排最坏情况下是O(n^2),

49,长度为N的数组乱序存放着0带N-1.现在只能进行0与其他数的swap操作,请设计并实现排序,必须通过交换实现排序。

50,有个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后{a1,b1,a2,b2,....,an,bn},要求时间复杂度o(n),空间复杂度0(1)。

51,如何找到一个数组中的两个数,他们的和为0

52,数组a[n]里存有1到n的所有树,除了一个数removed,找出这个missing的树

53,20个排序好的数组,每个数组500个数,按照降序排序好的,让找出500个最大的数。

54,一在线推送服务,同时为10万个用户提供服务,对于每个用户服务从10万首歌的曲库中为他们随机选择一首,同一用户不能推送重复的,设计方案,内存尽可能小

55,实现完整顺序表(Init,Search,Insert,Update,Delete,Length

56,二分查找

 

int binarySearch(int *array,int start,int end ,int value){

    int mid = start+ (end-start)/2;
        if(value ==array[mid] ) {
            return mid;
        
        }
        if(value > array[mid]){
            start = mid+1;
            
        }    
        else{
            end = mid-1;
            
        }    
        if(end<start){
        
            return -1;
        }                
        else{
            return binarySearch(array, start,end,value);
        
        }


    return 0;
}

 

 

 

57,实现完整哈希表(Init,Search,Insert,Update,Delete,Length

58,把list2没有的元素加到list1里 void Union(List<int> list1,List<int> list2){}

 

59,顺序表的Merge SeqList MergeList(SeqList list1,SeqList list2){}