java 确定ArrayList中最后一个整数最大的5个整数

ecbunoof  于 2023-05-05  发布在  Java
关注(0)|答案(4)|浏览(180)

假设我有一个没有重复的整数的排序ArrayList:
ArrayList<Integer> al = new ArrayList<>(Arrays.asList(3, 5, 7, 8, 9, 10, 11, 12, 14, 15));
假设保证列表中存在至少5个数字的序列。
我在试着找出最后一个数字最大的5个数列。在这种情况下,它将是:
[8, 9, 10, 11, 12](这个结果的顺序对我来说无关紧要)
这是我的想法

public class Game {

    public static void test2(ArrayList<Integer> al) {
        ArrayList<Integer> newArrayList = new ArrayList<>();
        Collections.reverse(al);
        System.out.println("list before: " + al);
        for (int i = 1; i < al.size(); ++i) {
            if (al.get(i) == al.get(i - 1) - 1) {
                newArrayList.add(al.get(i - 1));
            }
            if (newArrayList.size() == 5) {
                break;
            }
        }
        System.out.println("new list: " + newArrayList);
    }

    public static void main(String[] args) {
        ArrayList<Integer> al = new ArrayList<>(Arrays.asList(3, 5, 7, 8, 9, 10, 11, 12, 14, 15));
        test2(al);
    }

}

这将产生以下列表:
[15, 12, 11, 10, 9]而不是[12, 11, 10, 9, 8]
我知道为什么我的解决方案不起作用,但不知道如何修复它。

u1ehiz5o

u1ehiz5o1#

感谢您的回复。
我不知道这是不是最优雅的解决方案,但我想出了一个解决方案。

public static void test2(ArrayList<Integer> al) {
        ArrayList<Integer> newArrayList = new ArrayList<>();
        Collections.reverse(al);
        System.out.println("original list: " + al);
        for (int i = 1; i < al.size(); ++i) {
            if (al.get(i) == al.get(i - 1) - 1 ) {
                newArrayList.add(al.get(i - 1));
                if (i == al.size() - 1 || newArrayList.size() == 4) {
                    newArrayList.add(al.get(i));
                }
            } else {
                newArrayList.clear();
            }
            if (newArrayList.size() == 5) {
                break;
            }
        }
        System.out.println("new list: " + newArrayList);
    }

original list: [22, 21, 20, 16, 15, 14, 12, 11, 10, 9, 8, 7, 5, 3, 2]
new list: [12, 11, 10, 9, 8]
original list: [11, 8, 7, 6, 5, 4]
new list: [8, 7, 6, 5, 4]
original list: [8, 7, 6, 5, 4, 2]
new list: [8, 7, 6, 5, 4]
2guxujil

2guxujil2#

以下是一个解决方案:

  • 使用isValid辅助方法来分析当前和候选子列表。
  • 使用subLists来避免创建单独的列表(子列表显示主列表的视图,因此不会复制元素)。
  • 避免通过向后迭代来反转父列表。
List<Integer> list = List.of(1,2,3,4,5,16,17,18,19,22,23,24,47,48,90);

检查含有1至5个元素的系列溶液。

for (int limit = 5; limit > 0; limit--) {
     System.out.printf("For limit = %d : %s%n",limit, getMax(list, limit));
}

印刷品

For limit = 5 : [1, 2, 3, 4, 5]
For limit = 4 : [16, 17, 18, 19]
For limit = 3 : [22, 23, 24]
For limit = 2 : [47, 48]
For limit = 1 : [90]

主例程,它遍历大小限制的子列表,如果找不到,则返回有效的子列表或null

public static List<Integer> getMax(List<Integer> list, int limit) { 
    for (int i = list.size()-limit; i >= 0; i--) {
        List<Integer> candidate = list.subList(i,i+limit);
        if (isValid(candidate)) {
            return candidate;
        }
    }
    return null;
}

如果候选项是大小为limit的有效算术序列,则返回true。否则返回false

public static boolean isValid(List<Integer> candidate) {
    for (int i = candidate.size()-1; i > 0; i--) {
        if (candidate.get(i) - 1 != candidate.get(i-1)) {
            return false;
        }
    }
    return true;
}
wfypjpf4

wfypjpf43#

这应该做到:

public static void main(String[] args) {
    ArrayList<Integer> al = new ArrayList<>(Arrays.asList(3, 5, 7, 8, 9, 10, 11, 12, 14, 15));
    ArrayList<Integer> al2 = new ArrayList<>(Arrays.asList(10, 9, 8, 7, 6, 5, 4));
    ArrayList<Integer> al3 = new ArrayList<>(Arrays.asList(45, 23, 214, 123, 12, 67, 45, 23, 546, 234, 12, 23));
    test2(al);
    test2(al2);
    test2(al3);
}

public static void test2(List<Integer> al) {
    System.out.println("list before: " + al);
    
    Integer maxValue = al.get(4);
    Integer maxValuePosition = 4;   
    for (int i = 5; i < al.size(); ++i) {
        if (al.get(i) > maxValue) {
            maxValue = al.get(i);
            maxValuePosition = i;
        }
    }
    
    System.out.println("max value position: " + maxValuePosition);
    
    List<Integer> newArrayList = al.subList(maxValuePosition - 4, maxValuePosition + 1);
    System.out.println("new list: " + newArrayList);
}
iyzzxitl

iyzzxitl4#

你的明显问题是缺乏如何调试的知识。
考虑到你在SO上问了这个问题,显然你认为一个经验丰富的程序员只是盯着代码看了一会儿,然后跳出浴缸,跑到街上,大喊Eureka 。
不是这样的
你去调试。很简单的!你安排了一个系统,通过这个系统你可以看到你的代码正在做什么,你可以“在你的头脑中”或者在纸上计算出你认为它应该做什么。
两个人不同意的时候,耶!您发现了一个(1)bug。可能还有更多;修复它,重新开始,或者继续。一旦软件完全按照您的预期运行,就可以了。现在起作用了把它运出去。
所以,去吧,去做吧。学习如何使用调试器通常是一个好主意(它们通过让您看到表达式和变量的值,并一次运行一行代码来使此变得容易),但如果现在这听起来太费力(这不好;你可能听说过懒惰是一种美德--那不是你想要培养的那种懒惰),在这种情况下,总是会注入大量的Sysout语句。
我特别建议你检查一下,当你收集的“5的子序列”在中途失败时,newArraylist会发生什么,即15 - check,14 - still check,12 - uhoh,原来15不是你要找的5个数字序列中的最后一个数字。那么,当这种情况发生时,您的代码会做什么呢?
别想了只要去编辑你的代码,让你的代码告诉你在这种情况下它会做什么。与你想让它做的事情对比,你就会得到答案。

相关问题