【问题标题】:Next Greater Even Number下一个更大的偶数
【发布时间】:2017-02-27 20:47:56
【问题描述】:

我们有一个数字 N,问题是找到最小的偶数 E,使得 E > N 并且 N 和 E 中的数字相同。 N 中的数字可能很大。

例如

  1. 1 -> 34722641 答案是 34724126
  2. 111 -> 不可能有比它更大的偶数。
  3. 1123 -> 输出为 1132

我通过对数字的所有数字进行排列来用蛮力完成它。我在想是否有更好的方法呢?有代码会更好。

谢谢。

【问题讨论】:

    标签: algorithm stl-algorithm


    【解决方案1】:

    您可以使用以下策略来寻找下一个排列:

    让我们说你的number = 12344875 为了找到下一个更大的排列,你从右边开始,发现第一个数字比前一个小。 在这种情况下:number = 12344875,这是 4。

    现在你从向右移动的 4 开始,找到那里最小的数字。 这是 5 -> 875。现在交换这两个数字,得到 12345874

    交换后,按升序对 5 之后的数字进行排序。 12345874 --> 12345784。 这种策略总是会导致下一个更大的排列,只有这会给出偶数和奇数。

    所以为了找到下一个偶数排列,你需要稍微改变一下。 如果在最后一步中你有一个偶数,则排列该部分直到它的偶数。

    否则从右边重新开始。并找到第一个偶数,它的右侧有一个更大的数字。例如数字 = 123475531。 现在交换其右侧大于 4 的最小数字。 导致以下 123575431.

    从这里把偶数4放在最后,把数字放在中间 交换后的数字按升序排列,123575314 --> 123513574。

    如果您有以下数字 136531。没有偶数比右边更大的数字。所以你看下一个数字, 看看右边是否有一个更大的数字(但不是第一个偶数)。这里是 136531 --> 136531 所以交换它们并将偶数放在后面,最后按升序排列。 136531 --> 156331 --> 153316 --> 151336。 p>

    当数字按降序排列时(例如 97654)没有解决方案。

    在进行此解释时,我意识到对于偶数,这变得更加复杂。稍后我会尝试改进答案。

    我希望这很有用。 干杯

    【讨论】:

    • 你的方法看起来不错。但我在想它是否可以更优化排序 O(nlogn)。或者更确切地说,如果数字是奇数,我们可以避免你提到的那种排列。
    • 我今天没有时间。我今晚尝试制作一个伪代码,用于不均匀/偶数的情况。
    • 而且我认为老实说,上述内容始终是 O(n) 的顺序。您实际上不必在任何地方进行置换,这只是一个更快的描述。您可以在那个阶段选择最大的偶数并将其放在最后,然后将其余数字按升序排列。 1235131863 --> 1235131863 --> 1235133861 --> 1235133186.
    • 但是你正在做一个排序,它本身就是(nlogn),因为数字可以有大订单的数字。无论如何,仍然可以找到更好的解决方案,感谢您的努力。
    • 您的 976173 示例将 977136 作为下一个更大的偶数。更新你的答案。 您错过了一个非常重要的案例,其中有一个偶数,而右侧还有另一个相等的偶数。 例如 - 123646531 和 123696531。
    【解决方案2】:

    找到最右边的数字i,它的右边有一个更高的数字j,其中j 不是它右边的最高偶数数字e。选择最小的j,切换ij,将e作为最右边的数字,然后将i右侧的数字排序(升序)(不包括e)。

    【讨论】:

      【解决方案3】:
      1. 查找给定数字的下一个更大的数字。例如 - 对于 1234,下一个更大的数字是 1243,对于 534976,下一个更大的数字是 536479。 算法可以在here.找到
      2. 否则,重复上述步骤,直到找到偶数。即——找到下一个更大的偶数 数字比这与现在新的输入数字作为那个 我们在上一步中输出(即使我们没有找到想要的 输出(更大的偶数))

      例如 - 输入数字 - 21856521,运行第一步产生 - 21861255(奇数),因此我们再次在 21861255 上运行第 1 步产生 21861525(再次奇数),再次运行产生 21861552

      PS:C++代码:

      #include<iostream>
      #include<algorithm>
      #include<cstring>
      using namespace std;
      
      int main(){
          string s;cin>>s;
          int n = s.length();
          while(true){
              int idx = -1;
              for(int i=n-2;i>=0;--i){
                  if(s[i]<s[i+1]){
                      idx = i;
                      break;
                  }
              }
              if(idx==-1){
                  cout<<-1<<endl;
                  break;
              }
              int swapidx = -1;
              for(int i=n-1;i>=idx+1;--i){
                  if(s[i]>s[idx]){
                      swapidx = i;
                      break;
                  }
              }
              swap(s[idx],s[swapidx]);
      
              //swapidx will never remain -1 bcz. we will surely find an element greater than s[idx](the right next element to idx is greater than s[idx])
      
      
              sort(s.begin()+idx+1,s.end());
      
              if((s[n-1]-'0')%2==0){
                  cout<<s<<endl;
                  break;
              }
          }
          return 0;
      }
      

      【讨论】:

      • @GijsDenHollander If the last digit is even then you've found the next greater even number. Otherwise, .....repeat.
      猜你喜欢
      • 2015-01-04
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多