计算最长连败的总损失

时间:2020-05-09 19:12:56

标签: java

一个连续的数字序列,其中每个数字小于等于前一个数字,称为丢失连胜。条纹的最后一个数字和第一个数字之间的差值称为损失。

例如,如果标准输出中提供了这些数字:

3, 6, 36, 32, 32, 121, 66, 24, 22, 371, 661, 6, 4, 8.

序列中最长的条纹为36,32,32121,66,24,22661,6,4,相应的损失为4、99和657。在这种情况下,具有4个数字的第二个条纹最长。因此程序应将输出打印为99。

我尝试了以下程序,但无法正确执行:

public class LoosingStreak {

    public static void main(String[] args) {
        int arr [] = {3, 6, 36, 32, 32, 121, 66, 24, 22, 371, 661, 6, 4, 8, -1};
        int temp [] = new int[arr.length];
        processArray(arr);
    }

    static int processArray(int [] arr) {
        int temp [] = new int[arr.length];
        int len = arr.length;
        for(int i=0; i<len-1; i++) {
            if(arr[i+1] <= arr[i]) {
                temp[i] = arr[i];
                System.out.println(temp[i]);
            }

        }

        return -1;
    }

}

输出为:36, 32, 121, 66, 24, 661, 6, 8,这是不正确的。如何解决该问题?

3 个答案:

答案 0 :(得分:2)

您需要跟踪当前最长的条纹以及此长度的条纹的当前最大损耗。如果发现条纹超过最大条纹,请更新最长条纹和最大损耗。如果发现与当前最长长度相同的条纹,请更新最大损耗(如果更大)。

static int processArray(int [] arr) 
{
    int longestStreak = 0;
    int maxLoss = 0;
    for(int j=0, i=1; i<=arr.length; i++)
    {
        if(i == arr.length || arr[i] > arr[i-1])
        {
            int streak = i - j;
            if(streak > 1 && streak >= longestStreak)
            {
                int loss = arr[j] - arr[i-1];
                if(streak > longestStreak)
                {
                    longestStreak = i-j;                
                    maxLoss = loss;
                }
                else if (loss > maxLoss)
                    maxLoss = loss;                 
            }
            j = i;
        }
    }
    return longestStreak > 0 ? maxLoss : -1;
}

请注意,我要让条纹由连续的数字组成,这些数字要小于或等于前一个数字,因此单身人士将不是条纹。

测试:

int test[][] = {{1},
                {1, 1},
                {1, 2, 3},
                {3, 2, 1},
                {3, 2, 1, 4, 2, 1},
                {3, 6, 36, 32, 32, 121, 66, 24, 22, 371, 661, 6, 4, 8, -1}};

for(int[] arr : test)
    System.out.format("%s : %d%n", Arrays.toString(arr), processArray(arr));

输出:

[1] : -1
[1, 1] : 0
[1, 2, 3] : -1
[3, 2, 1] : 2
[3, 2, 1, 4, 2, 1] : 3
[3, 6, 36, 32, 32, 121, 66, 24, 22, 371, 661, 6, 4, 8, -1] : 99

答案 1 :(得分:1)

您必须寻找最长的条纹并同时计算损失。开始条纹时,请计算其电流损耗。条纹结束时,您可以将当前的条纹长度与迄今为止所看到的最长的条纹进行比较。如果新条纹较长,请对其进行更新并使其丢失。比您重设当前的条纹大小和电流损失。

static int processArray(int [] arr) {
    int streak = 0;
    int maxStreak = 0;
    int loss = 0;
    int maxLoss = 0;

    for(int i=0; i<arr.length-1; i++) {
        if(arr[i+1] <= arr[i]) {
            streak++;
            loss += arr[i] - arr[i+1];     
        }
        else{
            streak = 0;
            loss = 0;
        }
        if(streak > maxStreak){
            maxStreak = streak;
            maxLoss = loss;
        }
    }

    return maxLoss;
}

答案 2 :(得分:0)

您需要一个计数器,一些索引跟踪器(用于跟踪链和最长链的索引)和最大跟踪器(用于跟踪最长链),如下面给出的算法所述:

  1. 只要数字按降序排列,请增加计数器的值以及跟踪该顺序失败的元素的索引的变量的值。
  2. 订单失败时,将startend位置重置为订单失败的索引,并将count重置为0。重置这些值之前,请检查最后一个链是否最长(通过比较maxcount的值)并相应地设置max的值。
public class Main {
    public static void main(String[] args) {
        int arr[] = { 3, 6, 36, 32, 32, 121, 66, 24, 22, 371, 661, 6, 4, 8, -1 };
        int temp[] = new int[arr.length];
        System.out.println(longestLosingStreakLoss(arr));
    }

    static int longestLosingStreakLoss(int[] arr) {
        int start = 0, end = 0, count = 0, max = count, rangeLow = 0, rangeHigh = 0;

        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i + 1] <= arr[i]) {
                count++;
                end++;
            } else {
                if (count > max) {
                    max = count;
                    rangeHigh = end;
                    rangeLow = rangeHigh - count;
                }
                start = i + 1;
                end = start;
                count = 0;
            }
        }
        return rangeLow != rangeHigh ? arr[rangeLow] - arr[rangeHigh] : (count > 0 ? arr[0] - arr[arr.length - 1] : 0);
    }
}

输出:

99