c#查找最长连续子数组第一个和最后一个元素索引

Posted

技术标签:

【中文标题】c#查找最长连续子数组第一个和最后一个元素索引【英文标题】:c# Find the Longest Continuous Subarrays first and last elements Indexes 【发布时间】:2022-01-03 22:00:05 【问题描述】:

在输入的第一行中,有两个数字,第一个是行数N,第二个是限制K。我必须找到最长连续子数组的第一个和最后一个元素的索引,其元素大于 K

(有很多不同数字的输入,但它们的基数相同。)

示例输入为:

7 20
18
23
44
32
9
30
26

所以 N 是 7,K 是 20,在这种情况下,有 2 个连续子数组是正确的:[23,44,32] 和 [30 , 26],但我只需要较长的索引。

因此输出为:

1 3

我已经拆分了第一行,所以我有 NK,我在数组 H[] 中添加了剩余的行。现在我只需要找到最长的连续子数组并获取第一个和最后一个元素的索引。

static void Main(string[] args)
        
            string[] fRow = Console.ReadLine().Split(' ');
            int N = int.Parse(fRow[0]);
            int K = int.Parse(fRow[1]);
            int[] H = new int[N];
            for (int i = 0; i < N; i++)
            
                H[i] = int.Parse(Console.ReadLine());
            
        

我被困在这里,如果有人可以帮助我,我将非常感谢他们的帮助。

【问题讨论】:

【参考方案1】:

听起来像是家庭作业,但仍然是一个有趣的挑战。这是一种方法。

static void Main(string[] args)

    string[] fRow = Console.ReadLine().Split(' ');
    int N = int.Parse(fRow[0]);
    int K = int.Parse(fRow[1]);
    int[] H = new int[N];
    
    for (int i = 0; i < N; i++)
    
        H[i] = int.Parse(Console.ReadLine());
    

    int greatesRangeStartIndex = -1;
    int greatestRangeEndIndex = -1;
    int greatestIndexSpan = 0;
    
    for (int i = 0; i < N; i++)
    
        // Find the first array item that meets the criteria.
        if (H[i] > K)
        
            var rangeStartIndex = i;

            // Continue spinning through the array while we still meet the criteria.
            do
            
                i++;
             while (i < N && H[i] > K);

            var rangeEndIndex = i - 1;
            
            // Determine the width of our current range and check if its our largest one.
            // If the range is the biggest so far, store that as the current largest range.
            var indexSpan = rangeEndIndex - rangeStartIndex + 1;
            if (indexSpan > greatestIndexSpan)
            
                greatesRangeStartIndex = rangeStartIndex;
                greatestRangeEndIndex = rangeEndIndex;
                greatestIndexSpan = indexSpan;
            
        
    

    // Report out the results.
    // Not part of the requirements, but will remove false reporting of the criteria being in index position 1.
    if (greatesRangeStartIndex == -1 && greatestRangeEndIndex == -1)
    
        Console.WriteLine($"No values in the array were greater than K.");
    
    else
    
        Console.WriteLine($"greatesRangeStartIndex greatestRangeEndIndex");
    

【讨论】:

看起来最有效,也是唯一正确解析所有ints的答案,而不是在循环中解析它们【参考方案2】:

你可以做这样的事情(可以用 LINQ 改进很多,但我想这是某种介绍练习,所以我会坚持这个):

        static void Main(string[] args)
        
            string[] fRow = Console.ReadLine().Split(' ');
            int N = int.Parse(fRow[0]);
            int K = int.Parse(fRow[1]);
            int[] H = new int[N];
            int firstIndex = 0;
            int lastIndex = 0;
            int subarraySize = 0;

            int firstIndexTemp = 0;
            int lastIndexTemp = 0;
            int subarraySizeTemp = 0;
            bool arrayContinues = false;
            for (int i = 0; i < N; i++)
            
                //Read the newest index
                H[i] = int.Parse(Console.ReadLine());
                /*If arrrayContinues is true, and the current value is higher than the threshold K,
                  this means this is the continuation of a subarray. For now, the current value is the last index value
                  */
                if (H[i] > K && arrayContinues)
                
                    subarraySizeTemp++;
                    lastIndexTemp = i;
                
                /*If arrrayContinues is false, but the current value is higher than the threshold K,
                  this means this is the first index of a new subarray
                  */
                else if (H[i] > K)
                
                    subarraySizeTemp = 1;
                    firstIndexTemp = i;
                    arrayContinues = true;
                
                /*If we reach this statement, the current value is smaller than K,
                 * so the array streak stopped (or was already stopped by a previous smaller value)
                 */
                else
                
                    arrayContinues = false;
                

                /* We're only interested in the largest subarray,
                 * so let's override the previous largest array only when the current one is larger.
                 */
                if(subarraySizeTemp > subarraySize)
                
                    subarraySize = subarraySizeTemp;
                    firstIndex = firstIndexTemp;
                    lastIndex = lastIndexTemp;
                

            
            /*Let's print our result!*/
            Console.WriteLine($"firstIndex lastIndex");
        

【讨论】:

【参考方案3】:

其他答案可行,但您可以使用像这样更简单的方法;

private static void Main()

    var input = Console.ReadLine().Split(' ');
    var n = int.Parse(input[0]);
    var k = int.Parse(input[1]);

    var startingIndex = 0;
    var endingIndex = 0;

    var temporaryIndex = 0;

    var items = new int[n];

    for (var i = 0; i < n; i++)
    
        var value = int.Parse(Console.ReadLine());
        items[i] = value;

        if (value < k)
        
            temporaryIndex = i;
            continue;
        

        var currentSize = i - temporaryIndex;
        var currentBiggestSize = endingIndex - startingIndex;

        if (currentSize > currentBiggestSize)
        
            startingIndex = temporaryIndex + 1;
            endingIndex = i;
        
    

    Console.WriteLine($"Biggest Subset's Start and Ending Indexes: startingIndex endingIndex");
    Console.ReadLine();

【讨论】:

【参考方案4】:

另一种选择:

static void Main(string[] args)

    Example(new string[]  "7","20",new string[]  "18", "23", "44", "32", "9", "30", "26");


static void Example(string[] arr,string[] values)

    int N = int.Parse(arr[0]);
    int K = int.Parse(arr[1]);

    int counter = 0;
    int most_succesfull_index_yet = 0;
    int most_succesfull_length_yet = 0;
    for (int i = 1; i < N; i++)
    
        if (int.Parse(values[i]) > K)
        
            counter++;
        
        else
        
            if (counter > most_succesfull_length_yet)
            
                most_succesfull_length_yet = counter;
                most_succesfull_index_yet = i - counter;
            

            counter = 0;
        
    

    // For last index
    if (counter > most_succesfull_length_yet)
    
        most_succesfull_length_yet = counter;
        most_succesfull_index_yet = N - counter;
    

    var bestStart = most_succesfull_index_yet;
    var bestEnd = most_succesfull_index_yet + most_succesfull_length_yet -1;

    Console.WriteLine(bestStart + "," + bestEnd);
    Console.ReadLine();

【讨论】:

【参考方案5】:

另一种解决方案,保留最长匹配的索引,并在末尾显示最大长度、索引和行值。

        static void Main(string[] args)
        
            var data = @"7 20
18
23
44
32
9
30
26";
            var rows = data.Split("\r\n");
            var frow = rows[0].Split(" ");
            int N = int.Parse(frow[0]);
            int K = int.Parse(frow[1]);

            int max = 0, currentmax = 0;
            int i = 1;
            int[] indexes = null;

            while(i < rows.Length)
            
                if (int.Parse(rows[i]) > K)
                
                    currentmax++;
                
                else
                
                    if (currentmax > max)
                    
                        max = currentmax;
                        indexes = new int[max];
                        indexes[--currentmax] = i;
                        do
                        
                            indexes[--currentmax] = indexes[currentmax + 1] - 1;
                         while (currentmax > 0);

                        currentmax = 0;
                    
                
                i++;
            

            if (indexes != null) 
                Console.WriteLine($"max occured on indexes string.Join(",", indexes) with values string.Join(",", indexes.Select(i => rows[i]).ToList())");
            
        

【讨论】:

【参考方案6】:
string[] fRow = Console.ReadLine().Split(' ');
int N = int.Parse(fRow[0]);
int K = int.Parse(fRow[1]);


bool isChain = false;
int currentFirstIndex = -1;
int maxFirstIndex = -1;
int currentLastIndex = -1;
int maxLastIndex = -1;
int currentLength = 0;
int maxLength = 0;

int[] H = new int[N];
for (int i = 0; i < N; i++)

   H[i] = int.Parse(Console.ReadLine());
   if(H[i] > K)
   
      if (isChain)
      
         currentLastIndex = i;
      
      else
      
         currentFirstIndex = i;
         isChain = true;
      
      currentLength++;
   
   else
   
       if (maxLength < currentLength)
       
          maxLength = currentLength;
          maxFirstIndex = currentFirstIndex;
          maxLastIndex = currentLastIndex;
       
                       
       currentLength = 0;
       isChain = false;

    


Console.WriteLine("first: " + maxFirstIndex + "    last: " + maxLastIndex);

【讨论】:

【参考方案7】:

这可能是其中一种方式

    static void Main(string[] args)
    
        var firstLineInput = Console.ReadLine().Split(" ");
        var numberOfInput = Int64.Parse(firstLineInput[0]);
        var value = Int64.Parse(firstLineInput[1]);

        var startIndex = -1; //No value greater than value
        var endIndex = -1;

        var maxLength = 0;
        var maxStartIndex = -1;
        var maxEndIndex = -1;

        for (int i = 0; i < numberOfInput ; i++)
        
            var input = Int64.Parse(Console.ReadLine());
            
            if (input > value && startIndex == -1)
            
                startIndex = i;
                endIndex = i;

                if(maxLength == 0) 
                
                    maxLength = 1;
                    maxStartIndex = startIndex;
                    maxEndIndex = endIndex;
                
            
            else if(input > value && startIndex != -1) 
            
                endIndex = i;
            
            else if(input < value) 
            
                startIndex = -1;
                endIndex = -1;
            

            if (maxLength < (endIndex - startIndex))
            
                maxLength = endIndex - startIndex;
                maxStartIndex = startIndex;
                maxEndIndex = endIndex;
            
        

        Console.WriteLine($"maxStartIndex maxEndIndex");
    

【讨论】:

以上是关于c#查找最长连续子数组第一个和最后一个元素索引的主要内容,如果未能解决你的问题,请参考以下文章

算法——查找:最长连续递增子序列(部分有序)

最多具有K个元素的最大连续子数组

代码随想录算法训练营第五十二天 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

常用算法JS实现汇总

LIS最长上升子序列

第02次作业-线性表