2017/09/19 百度面试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Laox1ao/article/details/78036216

1、对于数组A,求出数组中连续子序列的最大和,如[1, 2, 3, 3, -4, 3, 0]的和最大连续子序列为[1, 2, 3, 3],最大和为9。

  • 解法一:暴力遍历,两个for循环,加上求出所有子序列的和操作,算法复杂度为O(n3),若把之前的计算过的和存起来,则可减少为O(n2):
def maxsum1(nums):
    maxsum = 0
    for i in range(len(nums)):
        sum = 0
        for j in range(i,len(nums)):
            sum += nums[j]
            if sum>maxsum:
                maxsum = sum
    return maxsum
  • 解法二:分治法,最大连续子序列和要么出现在数组左半部分,要么出现在数组右半部分,要么横跨左右两半部分。因此求出这三种情况下的最大值就可以得到最大连续子序列和,时间复杂度为O(nlogn)。
def maxsum2(nums, l, r):
    if l>r: return 0
    if l==r: return nums[l]
    mid = (l+r)/2
    lmax, rmax = 0, 0
    lsum, rsum = 0, 0
    for i in range(l,mid+1)[::-1]:
        lsum += nums[i]
        if(lsum>lmax):
            lmax = lsum
    for i in range(mid+1,r+1):
        rsum += nums[i]
        if(rsum>rmax):
            rmax = rsum
    return max(lmax+rmax, maxsum2(nums,l,mid), maxsum2(nums,mid+1,r))
  • 解法三:还有一种O(n)解法,一般最优解法都是需要深入分析具体问题的,本题的连续子序列,所有情况都是以0,n-1中某一元素为结尾,所以遍历到以第i个元素结尾的连续子序列时,判断当以第i-1个元素结尾的连续子序列,如果和为正数,那么就直接加上第i个元素,如果为负数或者为零,则以第i个元素结尾的连续子序列最大和即为第i个元素:
def maxsum3(nums):
    maxsum, maxhere = nums[0], nums[0]
    for i in range(1,len(nums)):
        if maxhere<=0:
            maxhere = nums[i]
        else:
            maxhere += nums[i]
        if maxhere>maxsum:
            maxsum = maxhere
    return maxsum

2、爬楼梯问题:一共有n级楼梯,从下往上,每次只能跨一级,两级,三级,共三种跨法,问一共有多少种爬法。再问:加上这样的规则,若这次跨了一次三级的台阶,则由于劳累而不能再跨一次三级,即不能连续跨三级楼梯,但是一、二级楼梯没有限制,问共有几种爬法。

  • 无规则:典型的DP问题。d[i]为到达第i级楼梯的所有爬法:
def climbstep(n):
    d = [0 for _ in range(n+1)]
    d[0], d[1], d[2] = 1, 1, 2
    for i in range(3,n+1):
        d[i] = d[i-1] + d[i-2] + d[i-3]
    return d[n]
  • (待解决)有规则:
Coding Here

3、有两个乱序且元素不重复的数组A,B,数组长度分别为m,n,求两个数组中所有相同的元素。

  • 当场解法:1、暴力遍历,时间复杂度为O(mn)。2、对A排序(快排),遍历B,对于每个B中的元素在A中进行查找(二分查找),时间复杂度O(mlogm+nlogm):
def sameElement1(a, b):
    res = []
    quicksort(a)  #对A进行快排
    for i in range(len(b)):
        if binarysearch(a,b[i]):   #在A中进行二分查找
            res.append(b[i])
    return res
  • 另解:借用集合处理重复元素判断:
def sameElements(a, b):
    temp, same = set(a), list()
    for i in range(len(b)):
        len0 = len(temp)
        temp.add(b[i])
        len1 = len(temp)
        if len0 == len1:
            same.append(b[i])
    return same
  • 另解:直接使用集合的交集操作:
def sameElements(a, b):
    a, b = set(a), set(b)
    return list(a&b)

猜你喜欢

转载自blog.csdn.net/Laox1ao/article/details/78036216