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

如何用暴力法查找数组中的最大非递减子集?现有代码求验证

暴力法求解最大非递减子集的Java实现疑问

你好!咱们先明确需求:给定数组 (5, 12, 4, 6, 7, 12, 5, 55, 13, 14),要找出其中的最大非递减子集(你提到的示例是(4, 6, 7, 12)),并且要求用暴力法实现。先看你写的这段代码,它其实不属于暴力法——你的思路是遍历数组时维护当前的非递减序列,遇到下降就比较长度,这更像是一次遍历的贪心思路,但暴力法的核心是枚举所有可能的子集,再筛选符合条件的最长那个。

先给你拆解下暴力法的核心逻辑:

  • 枚举数组中所有可能的子序列(注意这里的子集是指元素保持原顺序的子序列,不是任意组合)
  • 对每个子序列,检查它是否是非递减的
  • 记录所有符合条件的子序列中长度最长的那个

暴力法的伪代码

初始化最长非递减子序列为空
遍历数组中每个起始索引i从0到n-1:
    初始化当前子序列为[arr[i]]
    遍历每个结束索引j从i+1到n-1:
        如果arr[j] >= 当前子序列的最后一个元素:
            将arr[j]加入当前子序列
            如果当前子序列长度 > 最长子序列长度:
                更新最长子序列为当前子序列的副本
        否则:
            继续下一个j(如果是找连续子数组则break,不连续则跳过)
    单独检查单个元素的情况(避免遗漏)
返回最长非递减子序列

你的代码问题分析

你的代码逻辑是在一次遍历中,遇到递增就追加元素,遇到递减就保存当前序列并重置,但这种方法会错过很多可能的非递减子序列。比如数组中的(5,12,55)或者(4,6,7,12,55)这类候选,而且核心是没有枚举所有可能的组合,不符合暴力法的定义。

暴力法的Java代码示例

针对连续非递减子数组的暴力实现

如果你的需求是找连续的最长非递减子数组(和你给出的示例匹配),代码如下:

import java.util.ArrayList;
import java.util.List;

public class LongestContinuousNonDecreasing {
    public static void main(String[] args) {
        int[] arr = {5, 12, 4, 6, 7, 12, 5, 55, 13, 14};
        List<Integer> longestSubset = findLongestContinuousNonDecreasing(arr);
        System.out.println("最长连续非递减子集:" + longestSubset);
    }

    public static List<Integer> findLongestContinuousNonDecreasing(int[] arr) {
        List<Integer> longest = new ArrayList<>();
        int n = arr.length;

        // 枚举所有起始位置
        for (int i = 0; i < n; i++) {
            List<Integer> current = new ArrayList<>();
            current.add(arr[i]);
            // 从起始位置往后扩展连续子数组
            for (int j = i + 1; j < n; j++) {
                if (arr[j] >= current.get(current.size() - 1)) {
                    current.add(arr[j]);
                } else {
                    // 连续子数组中断,跳出循环
                    break;
                }
            }
            // 更新最长序列
            if (current.size() > longest.size()) {
                longest = new ArrayList<>(current);
            }
        }
        return longest;
    }
}

针对不连续非递减子序列的暴力实现

如果是找不连续的最长非递减子序列,暴力法需要用回溯枚举所有可能的组合(时间复杂度O(2^n),非常低效,但符合暴力法定义):

import java.util.ArrayList;
import java.util.List;

public class LongestNonDecreasingSubsequence {
    private static List<Integer> longest;

    public static void main(String[] args) {
        int[] arr = {5, 12, 4, 6, 7, 12, 5, 55, 13, 14};
        longest = new ArrayList<>();
        backtrack(arr, 0, new ArrayList<>());
        System.out.println("最长非递减子序列:" + longest);
    }

    private static void backtrack(int[] arr, int start, List<Integer> current) {
        // 更新最长序列
        if (current.size() > longest.size()) {
            longest = new ArrayList<>(current);
        }

        for (int i = start; i < arr.length; i++) {
            // 满足非递减条件则加入当前序列
            if (current.isEmpty() || arr[i] >= current.get(current.size() - 1)) {
                current.add(arr[i]);
                backtrack(arr, i + 1, current);
                current.remove(current.size() - 1); // 回溯,尝试其他组合
            }
        }
    }
}

总结

你的代码是一次遍历的贪心策略,不属于暴力法。暴力法的核心是枚举所有可能的候选子序列,再逐一验证筛选,虽然效率低,但完全符合暴力法“穷尽所有可能”的定义。根据你的需求选择对应的实现即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:22:00