算法之求最大下标距离

出处:http://www.fengchang.cc/post/66

题干:输入:任意整型数组A

求满足约束条件A[i]<A[j] 且i<j的最大j-i

数学上是个最优化问题,暴力求法就不说了,n平方时间复杂度的大家都会。

这里给思路上的9个直觉,直觉是让你记住算法的终极武器,比代码重要,掌握了直觉,才算是真正理解。

源代码用python写的,放这里了https://github.com/fengchangfight/fcalgorithmplayground

其中的question1.py就是.

个人感觉比较重要的一点要有“子序列”思维,不是“子串”,“子串”是需要连续的,“子序列”不需要

不好意思用英文了:

from utils import randIntegerArrayGenerator
#############THE QUESTION IS###########
# input:an array of integer, let's call it A:
# constraint: A[i]<A[j], i<j
# optimization goal: maximize(j-1)
#######################################gs

# intuition 1: if not using any existing knowledge of the array, we have to compare each 2 elements of the array,
# which is obviously O(n2).

# intuition 2: let's fix the right side index, if there exist an left side index i, satisfy the constraint, than any element that is small than
# A[i] on the left side of i would be a greater choice, which means, for any incremented list, only the leftmost element could be the candidate for
# the one for choice, the others in the list are just not possible.  e.g. there is a sub list [3,4,5], sublist don't have to be consecutive,
# but needs to maintain the order it occurs in the original list, only 3 could be the left-side candidate,
# 4 and 5 are just not possible, so this is a very useful way to exclude useful element! but how do we use this feature? that is a higher level
# question.

# intuition 3: thinking in a symmetry way, if there is an incrementing sub list, only the right-most candidate could be the candidate,
# e.g. there is a sub list [3,4,5], only 5 could be the candidate, don't even need to think about 3 and 4, because, if any of the 2 is a choice,
# 5 would be a better choice

# intuition 4: can we pick out the subset of the possible left-end candidates and right-end candidates? and then do something?

# intuition 5: how many such increment subsequence do we need to pick? every increasing interval? or just one is enough?

# intuition 6: think in a subsequence way when dealing with array(not substring)

# intuition 7 think about fixing the left side(one side), and move from the other side,
# no move back and forth, think about why this is correct and prove it

# intuition 8, when we want to exclude a choice, we can prove it's correct by providing another obviously better choice

# intuition 9, think about equal case, which is very very very important

input = randIntegerArrayGenerator(10, 1,30)

def findDecreasingSubSequenceIndex(input_array):
    result = []
    for i in range(len(input_array)):
        if(len(result)<1):
            result.append(i)
        elif(input_array[i]<input_array[result[-1]]):
            result.append(i)
    return result


#sample input
#input = [26, 3, 24, 16, 10, 14, 22, 1, 19, 1]
print(input)


decIndex = findDecreasingSubSequenceIndex(input)
print(decIndex)
j = len(input)-1
iIndex = len(decIndex)-1
i = decIndex[iIndex]

maxDistance = j-i

while(True):
    iIndex-=1
    if(iIndex<0):
        break
    i = decIndex[iIndex]
    if(input[i]<=input[j]):
        newDistance = j-i
        if(newDistance>maxDistance):
            maxDistance = newDistance
        continue
    else:
        while(input[i]>input[j]):
            j-=1
        newDistance = j-i
        if(newDistance>maxDistance):
            maxDistance = newDistance

print(maxDistance)


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值