算法之求最大下标距离

出处: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)


 

### 找到数组或列表中的最大值及其对应下标 在多种编程语言中,可以实现查找数组或列表的最大值以及其对应的下标的功能。以下是几种常见编程语言的解决方案。 #### Python 实现 Python 提供了内置函数 `max()` 和 `index()` 来简化这一过程[^1]: ```python def find_max_and_index(lst): max_value = max(lst) # 获取最大值 index_of_max = lst.index(max_value) # 查找最大值的索引位置 return (max_value, index_of_max) lst = [3, 5, 7, 2, 8] result = find_max_and_index(lst) print(f"最大值为 {result[0]},位于下标 {result[1]}") ``` 上述代码通过调用 `max` 函数获取列表中的最大值,并利用 `list.index(value)` 方法返回该值首次出现的位置[^1]。 #### C++ 实现 C++ 中可以通过标准库 `<algorithm>` 的功能来完成此操作[^2]: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec = {3, 5, 7, 2, 8}; auto it = std::max_element(vec.begin(), vec.end()); // 返回指向最大元素的迭代器 int max_val = *it; // 解引用得到最大值 int index = std::distance(vec.begin(), it); // 计算距离起始位置的距离作为索引 std::cout << "最大值为 " << max_val << ", 下标为 " << index << std::endl; } ``` 这里使用了 STL 容器 vector 并借助于算法头文件中的工具函数 `std::max_element` 寻找范围内的最大值指针,再配合 `std::distance` 得出相对偏移量即为索引位置[^2]。 #### Java 实现 Java 可以手动遍历整个集合或者数组来进行比较并记录当前已知最大的数值连同它的索引号一起保存下来直到循环结束为止[^3]: ```java public class Main { public static void main(String[] args) { int[] array = {3, 5, 7, 2, 8}; int maxValue = array[0]; int indexOfMaxValue = 0; for(int i=1;i<array.length;i++) { if(array[i]>maxValue){ maxValue=array[i]; indexOfMaxValue=i; } } System.out.println("最大值为 "+maxValue+", 位于下标 "+indexOfMaxValue); } } ``` 这段程序初始化第一个元素为初始最大值,随后逐一检查后续每一个数是否更大;如果发现更大的,则更新这两个变量的内容直至全部处理完毕[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值