【问题标题】:Find the second maximum number in an array with the smallest complexity找到复杂度最小的数组中的第二个最大数
【发布时间】:2013-02-11 10:38:19
【问题描述】:

试图用谷歌搜索它,但没有运气。 如何在具有最小复杂度的数组中找到第二个最大数?

代码或想法会有很大帮助。

我可以遍历一个数组并查找最大数 之后,我有最大数量,然后再次循环数组以相同的方式找到第二个。

但肯定是没有效率的。

【问题讨论】:

  • 类似stackoverflow.com/questions/852439/…。然后拿第二个项目。
  • “最小复杂度”是什么意思?
  • 定义“复杂性”,我们是在谈论清晰的可维护代码吗?还是计算效率?
  • 最快最高效的算法

标签: c# .net


【解决方案1】:

You could sort the array and choose the item at the second index, but the following O(n) loop will be much faster.

int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
int largest = int.MinValue;
int second = int.MinValue;
foreach (int i in myArray)
{
 if (i > largest)
 {
  second = largest;
  largest = i;
 }
else if (i > second)
    second = i;
}

System.Console.WriteLine(second);

试试这个(使用 LINQ):

int secondHighest = (from number in test
                             orderby number descending
                             select number).Distinct().Skip(1).First()

How to get the second highest number in an array in Visual C#?

【讨论】:

  • 我喜欢 Linq 解决方案,它高效吗?请解释一下。
  • 是的,效率很高,也很好............它按“降序”的顺序对数字进行排序,然后跳过第一个并获得第二个。跨度>
  • 是的,我试过了,效果很好!和非常好的方法,我如何“衡量”其中的复杂性?
  • 问题:在 LINQ 实现中,它实际上会对整个数组进行排序吗?实际上,这在理论上不是必需的(您提出的第一个解决方案不会对其进行排序,它只是遍历一次)
  • 如果最大值有重复(这里是 13),第一种方法可能会输出不正确的结果
【解决方案2】:
public static int F(int[] array)
{
    array = array.OrderByDescending(c => c).Distinct().ToArray();
    switch (array.Count())
    {
        case 0:
            return -1;
        case 1:
            return array[0];
    }
    return array[1];
}

【讨论】:

    【解决方案3】:

    用 C# 回答:

    static void Main(string[] args)
            {
                //let us define array and vars
                var arr = new int[]{ 100, -3, 95,100,95, 177,-5,-4,177,101 };
    
                int biggest =0, secondBiggest=0;
                for (int i = 0; i < arr.Length; ++i)
                    {
                    int arrItem = arr[i];
                    if(arrItem > biggest)
                    {
                        secondBiggest = biggest; //always store the prev value of biggest 
                                                 //to second biggest...
                        biggest = arrItem;
                     }
                    else if (arrItem > secondBiggest && arrItem < biggest) //if in our 
                     //iteration we will find a number that is bigger than secondBiggest and smaller than biggest 
                       secondBiggest = arrItem;
                }
    
                Console.WriteLine($"Biggest Number:{biggest}, SecondBiggestNumber: 
                                  {secondBiggest}");
                Console.ReadLine(); //make program wait
            }
    

    输出:最大数:177,第二大数:101

    【讨论】:

      【解决方案4】:
       static void Main(string[] args)
          {
              int[] myArray = new int[] { 0, 11, 2, 15, 16, 8, 16 ,8,15};
              int Smallest = myArray.Min();
              int Largest = myArray.Max();
              foreach (int i in myArray)
              {
                  if(i>Smallest && i<Largest)
                  {
                      Smallest=i;
                  }
              }
              System.Console.WriteLine(Smallest);
              Console.ReadLine();   
          }
      

      即使您在数组中具有项目的声誉,这也将起作用

      【讨论】:

        【解决方案5】:
                   int[] arr = {-10, -3, -3, -6};
                   int h = int.MinValue, m = int.MinValue;
        
                            foreach (var t in arr)
                            {
                                if (t == h || t == m)
                                    continue;
                                if (t > h)
                                {                            
                                    m = h;
                                    h = t;
                                }
                                else if(t > m )
                                {                            
                                    m = t;
                                }
        
                            }
        
                    Console.WriteLine("High: {0} 2nd High: {1}", h, m);
                           //or,
                    m = arr.OrderByDescending(i => i).Distinct().Skip(1).First();
        
                    Console.WriteLine("High: {0} 2nd High: {1}", h, m);
        

        【讨论】:

        • 请注意,我们不鼓励仅使用代码回答。只是将代码转储给某人对未来的读者没有多大帮助。专注于解释你在做什么!
        • 这个答案与接受的答案或德米特里的答案有何不同?
        【解决方案6】:
        /* we can use recursion */
        var counter = 0;
             findSecondMax = (arr)=> {
        
                let max = Math.max(...arr);
                counter++;
                return counter == 1 ? findSecondMax(arr.slice(0,arr.indexOf(max)).concat(arr.slice(arr.indexOf(max)+1))) : max;
            }
        
            console.log(findSecondMax([1,5,2,3,0]))
        

        【讨论】:

          【解决方案7】:
          static void Main(string[] args){
              int[] arr = new int[5];
              int i, j,k;
              Console.WriteLine("Enter Array");
          
              for (i = 0; i < 5; i++) {
                  Console.Write("element - {0} : ", i);
                  arr[i] = Convert.ToInt32(Console.ReadLine());
              }
          
              Console.Write("\nElements in array are: ");
              j=arr[0];
              k=j;
          
              for (i = 1; i < 5; i++) {
                  if (j < arr[i])
                  {
                      if(j>k)
                      {
                          k=j;
                      }
                      j=arr[i];
                  }  
              }
          
              Console.WriteLine("First Greatest element: "+ j);
              Console.WriteLine("Second Greatest element: "+ k);
              Console.Write("\n");
          }
          

          【讨论】:

            【解决方案8】:
            int max = 0;
            int secondmax = 0;
            int[] arr = { 2, 11, 15, 1, 7, 99, 6, 85, 4 };
            
            for (int r = 0; r < arr.Length; r++)
            {
                if (max < arr[r])
                {
                    max = arr[r];
                }
            }
            
            for (int r = 0; r < arr.Length; r++)
            {
                if (secondmax < arr[r] && arr[r] < max)
                {
                    secondmax = arr[r];
                }
            }
            
            Console.WriteLine(max);
            Console.WriteLine(secondmax);
            Console.Read();
            

            【讨论】:

              【解决方案9】:

              Python 36>=

              def sec_max(array: list) -> int:
              _max_: int = max(array)
              second: int = 0
              for element in array:
                  if second < element < _max_:
                      second = element
                  else:
                      continue
              return second
              

              【讨论】:

                【解决方案10】:

                你的结构不是一棵树……它只是一个简单的数组,对吧?

                最好的解决方案是对数组进行排序。并根据降序或升序,分别显示第二个或倒数第二个元素。

                另一种选择是使用一些内置方法来获得初始最大值。弹出该元素,然后再次搜索最大值。不懂C#,所以不能直接给出代码。

                【讨论】:

                • 你可以用 O(n) 代替 O(2n) 或 O(n log n)。
                【解决方案11】:

                您想对数字进行排序,然后只取第二大的数字。这是一个不考虑效率的sn-p:

                var numbers = new int[] { 3, 5, 1, 5, 4 };
                var result=numbers.OrderByDescending(x=>x).Distinct().Skip(1).First();
                

                【讨论】:

                  【解决方案12】:

                  这还不错:

                  int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
                  
                  var secondMax =
                      myArray.Skip(2).Aggregate(
                              myArray.Take(2).OrderByDescending(x => x).AsEnumerable(),
                              (a, x) => a.Concat(new [] { x }).OrderByDescending(y => y).Take(2))
                          .Skip(1)
                          .First();
                  

                  它的复杂性相当低,因为它只对最多三个元素进行排序

                  【讨论】:

                    【解决方案13】:
                    namespace ConsoleApplication1
                    {
                        class Program
                        {
                            static void Main(string[] args)
                            {
                                int size;
                                Console.WriteLine("Enter the size of array");
                                size = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("Enter the element of array");
                                int[] arr = new int[size];
                                for (int i = 0; i < size; i++)
                                {
                                    arr[i] = Convert.ToInt32(Console.ReadLine());
                                }
                                int length = arr.Length;
                                Program program = new Program();
                                program.SeconadLargestValue(arr, length);
                            }
                    
                            private void SeconadLargestValue(int[] arr, int length)
                            {
                                int maxValue = 0;
                                int secondMaxValue = 0;
                                for (int i = 0; i < length; i++)
                                {
                                    if (arr[i] > maxValue)
                                    {
                                        secondMaxValue = maxValue;
                                        maxValue = arr[i];
                                    }
                                    else if(arr[i] > secondMaxValue)
                                    {
                                        secondMaxValue = arr[i];
                                    }
                                }
                                Console.WriteLine("First Largest number :"+maxValue);
                                Console.WriteLine("Second Largest number :"+secondMaxValue);
                                Console.ReadLine();
                            }   
                        }
                    }
                    

                    【讨论】:

                    • 如果您包含 cmets 或以其他方式描述它的作用而不是仅仅发布代码,这将更加有用。
                    【解决方案14】:

                    我的解决方案如下。

                        class Program
                        {
                          static void Main(string[] args)
                            {
                            Program pg = new Program();
                            Console.WriteLine("*****************************Program to Find 2nd Highest and 2nd lowest from set of values.**************************");
                            Console.WriteLine("Please enter the comma seperated numbers : ");
                            string[] val = Console.ReadLine().Split(',');
                            int[] inval = Array.ConvertAll(val, int.Parse); // Converts Array from one type to other in single line  or Following line
                            // val.Select(int.Parse)
                            Array.Sort(inval);
                            Console.WriteLine("2nd Highest is : {0} \n 2nd Lowest is : {1}", pg.Return2ndHighest(inval), pg.Return2ndLowest(inval));
                            Console.ReadLine();
                    
                            }
                    
                    
                            //Method to get the 2nd lowest and 2nd highest from list of integers ex 1000,20,-10,40,100,200,400
                    
                            public  int Return2ndHighest(int[] values)
                            {
                               if (values.Length >= 2)
                                  return values[values.Length - 2];
                               else
                                  return values[0];
                             }
                    
                             public  int Return2ndLowest(int[] values)
                             {
                                  if (values.Length > 2)
                                      return values[1];
                                  else
                                      return values[0];
                              }
                    
                         }
                    

                    【讨论】:

                    • 或 'code' int[] val = Array.ConvertAll(Console.ReadLine().Split(','), int.Parse); Array.Sort(val); int min = val.Min(); int max = val.Max(); int 长度 = val.Length; int Secondlowest = val.OrderBy(x => x).Skip(1).First(); int SecondHighest = val.OrderByDescending(x => x).Skip(1).First(); Console.WriteLine("第二高是: {0} \n 第二低是: {1}", SecondHighest, Secondlowest); Console.ReadLine(); '代码'
                    【解决方案15】:

                    我正在提供 JavaScript 中的解决方案,它需要 o(n/2) 复杂度才能找到最高和第二高的数字。
                    这是工作的Fiddler Link

                        var num=[1020215,2000,35,2,54546,456,2,2345,24,545,132,5469,25653,0,2315648978523];
                    var j=num.length-1;
                    var firstHighest=0,seoncdHighest=0;
                    num[0] >num[num.length-1]?(firstHighest=num[0],seoncdHighest=num[num.length-1]):(firstHighest=num[num.length-1],   seoncdHighest=num[0]);
                    j--;
                    for(var i=1;i<=num.length/2;i++,j--)
                    {
                       if(num[i] < num[j] )
                       {
                              if(firstHighest < num[j]){
                              seoncdHighest=firstHighest;
                               firstHighest= num[j];
                              }
                               else if(seoncdHighest < num[j] ) {
                                   seoncdHighest= num[j];
                    
                               }
                       }
                       else {
                           if(firstHighest < num[i])
                           {
                               seoncdHighest=firstHighest;
                               firstHighest= num[i];
                    
                           }
                           else if(seoncdHighest < num[i] ) {
                                seoncdHighest= num[i];
                    
                           }
                       }
                    
                    }   
                    

                    【讨论】:

                      【解决方案16】:

                      对数组进行排序并取倒数第二个值?

                      【讨论】:

                      • 排序并不是一个更小的复杂性。他现在得到 O(n)。除非使用 RADIX,否则排序只会将其增加到 O(n lg n)。
                      【解决方案17】:
                       var result = (from elements in inputElements
                          orderby elements descending
                          select elements).Distinct().Skip(1).Take(1);
                       return result.FirstOrDefault();
                      

                      【讨论】:

                      • 将对零元素起作用,当数组具有零元素时首先会中断。
                      【解决方案18】:
                      namespace FindSecondLargestNumber
                      {
                          class Program
                          {
                              static void Main(string[] args)
                              {
                                  int max=0;
                                  int smax=0;
                                  int i;
                                  int[] a = new int[20];
                                  Console.WriteLine("enter the size of the array");
                                  int n = int.Parse(Console.ReadLine());
                                  Console.WriteLine("elements");
                                  for (i = 0; i < n; i++)
                                  {
                                      a[i] = int.Parse(Console.ReadLine());
                      
                                  }
                                  for (i = 0; i < n; i++)
                                  {
                                      if ( a[i]>max)
                                      {
                                          smax = max;
                                          max= a[i];
                                      }
                                      else if(a[i]>smax)
                                      {
                                          smax=a[i];
                                      }
                                  }
                                  Console.WriteLine("max:" + max);
                      
                                  Console.WriteLine("second max:"+smax);
                                      Console.ReadLine();
                              }
                          }
                      }
                      

                      【讨论】:

                      • 如果您包含 cmets 或以其他方式描述它的作用而不是仅仅发布代码,这将更加有用。
                      • 您的代码格式不正确(只有大约一半),并且完全没有解释为什么这是解决问题的最低复杂性方法。
                      猜你喜欢
                      • 2018-04-07
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多