You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求长度为k的非连续子序列最大值的最小值:算法正确性验证

问题描述

给定数组,找出所有长度为k的非连续子序列(子序列中任意两个元素在原数组中不相邻),计算每个子序列的最大值,再求这些最大值中的最小值。例如数组[2,3,5,9]、k=2时,有效子序列为[2,5]、[3,9]、[2,9],最大值分别为5、9、9,最终结果为5。

我的情况

  • 已用C语言实现解决该问题的算法,所有测试用例均通过。
  • 为确保解决方案可靠,撰写了一份正确性证明,但不确定其质量。
  • 核心疑问:
    1. 编写的算法是否正确?
    2. 撰写的正确性证明是否正确?
  • 额外需求:
    • 希望得到算法、证明及C语言实现的优化建议
    • 若对原问题存在误解,请指出

算法说明

做了两个前提假设:

  • 输入序列元素唯一
  • 2≤k≤(序列长度+1)/2

算法核心逻辑:将数组升序排序,依次检查每个元素是否能作为长度为k的非连续子序列的最大值,找到第一个满足条件的元素即为结果。

正确性证明

定义了相关术语,证明了目标结果是能作为k长度非连续子序列最大值的最小元素,并说明了最长符合条件子序列的构造方式。

C语言实现

#include <limits.h> // For INT_MAX
#include <assert.h> // For assert
#include <string.h> // For memcpy
#include <stdlib.h> // For qsort

int compar (const void * first, const void * second) {
    if (* (int *)first < * (int *)second) return -1;
    else if (* (int *)first == * (int *)second) return 0;
    else return 1;
}

void find_k_size_sequence_maxes_min (int array_length, int array[], int k, int * result_min) {
    if (k < 2 || array_length < 2 * k - 1) return;

    int sorted[array_length];
    memcpy(sorted, array, sizeof (int) * array_length);
    qsort(sorted, array_length, sizeof (int), compar);

    for (int t = k - 1; t < array_length; ++t) {
        int index = -1;
        while (array[++index] != sorted[t]);

        int size = 1;

        int last_index = index;
        for (int u = index; u >= 0; --u) {
            if (u < last_index - 1 && array[u] <= sorted[t]) {
                ++size;
                last_index = u;
            }

            if (size >= k) {
                * result_min = sorted[t];
                return;
            }
        }

        last_index = index;
        for (int u = index; u < array_length; ++u) {
            if (u > last_index + 1 && array[u] <= sorted[t]) {
                ++size;
                last_index = u;
            }

            if (size >= k) {
                * result_min = sorted[t];
                return;
            }
        }
    }
}

int main (void) {
    // Test case 1
    int array1[] = { 6, 3, 5, 8, 1, 0, 9, 7, 4, 2, };
    int array1_length = (int)((double)sizeof array1 / sizeof (int));
    int k = 2;
    int min = INT_MAX;
    find_k_size_sequence_maxes_min(array1_length, array1, k, & min);
    assert(min == 2);

    // Test case 2
    int array2[] = { 1, 7, 2, 3, 9, 11, 8, 14, };
    int array2_length = (int)((double)sizeof array2 / sizeof (int));
    k = 2;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array2_length, array2, k, & min);
    assert(min == 2);

    // Test case 3
    k = 3;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array2_length, array2, k, & min);
    assert(min == 8);

    // Test case 4
    k = 4;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array2_length, array2, k, & min);
    assert(min == 9);

    // Test case 5
    int array3[] = { 3, 5, 4, 0, 8, 2, };
    int array3_length = (int)((double)sizeof array3 / sizeof (int));
    k = 3;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array3_length, array3, k, & min);
    assert(min == 3);

    // Test case 6
    int array4[] = { 18, 21, 20, 6 };
    int array4_length = (int)((double)sizeof array4 / sizeof (int));
    k = 2;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array4_length, array4, k, & min);
    assert(min == 18);

    // Test case 7
    int array5_length = 1000000;
    int array5[array5_length];
    for (int m = array5_length - 1; m >= 0; --m) array5[m] = m;
    k = 100;
    min = INT_MAX;
    find_k_size_sequence_maxes_min(array5_length, array5, k, & min);
    assert(min == 198);
}

补充说明

  • 经优化,排序后的循环可从t=k-1开始以减少迭代次数
  • 目前已在原问题下发布解答,仍欢迎进一步优化建议

内容的提问来源于stack exchange,提问作者user20276305

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:45:27