• + 72 comments

    Here is a good explanation of a next lexicographical permutation algorithm:

    http://www.nayuki.io/page/next-lexicographical-permutation-algorithm

    • + 2 comments

      This was helpful. Thanks!

      • + 0 comments

        Thanks. Here's the full solution in Python. Hackerrank - Bigger is Greater Solution

      • + 1 comment

        here is problem solution in java python c++ c and javascript programming.

        HackerRank Bigger is Greater problem solution

        • + 0 comments

          Can u explain what have you done in java solution?? Thanks in advance.

    • + 0 comments

      very nice solution

    • + 0 comments

      good logic !!!

    • + 6 comments

      Try to solve in Java. Calculating all next lexicographical permutation using this logic. But Test#1, #2 says 4s Terminated due to time out. Any suggestion?

      • + 5 comments

        test the case when input is just one letter (e.g. p), the output should be "no answer". This solved my problem.

        • + 2 comments

          no it didn't solved

          • + 0 comments

            first of all check if same letters are repeating

          • + 2 comments

            int main() {

            int t,i;
            
            cin >> t;
            
            string s;
            
            for(i=0;i<t;i++)
            {
            
             cin >> s;
            
            bool val = next_permutation(s.begin(), s.end());
            
            if (val == false)
            {
            
                cout << "no answer" << endl;
            
            }
            
            else
            
            {
            
                cout << s << endl;
            
            }
            

            }

             return 0;
            

            }

            • + 0 comments

              Possible implementation from cppreference.com

              template<class BidirIt>
              bool next_permutation(BidirIt first, BidirIt last)
              {
                  if (first == last) return false;
                  BidirIt i = last;
                  if (first == --i) return false;
               
                  while (true) {
                      BidirIt i1, i2;
               
                      i1 = i;
                      if (*--i < *i1) {
                          i2 = last;
                          while (!(*i < *--i2))
                              ;
                          std::iter_swap(i, i2);
                          std::reverse(i1, last);
                          return true;
                      }
                      if (i == first) {
                          std::reverse(first, last);
                          return false;
                      }
                  }
              }
              
        • + 0 comments

          thanks, it solved my problem.

        • + 0 comments

          Thanks. It helped to pass test cases #1 and #2

        • + 0 comments

          such a relief!!!

      • + 3 comments

        Try to use

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        

        to read the input. It has 100000 test cases so Scanner won't work

        • + 1 comment

          can you please tell how to BufferReader to scan multiple lines of Strings with Exception Handling

          • + 3 comments

            here is what i did:

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            int num = Integer.parseInt(in.readLine());
            String line = "";
            for (int i = 0; i < num; i++) {
            	line = in.readLine();
            	// Do your stuff here
            }
            
            • + 0 comments

              Thanks buddy

            • + 1 comment

              didn't work, i still get timeouts

              • + 1 comment

                I did this.. Lengthy but worked.

                import java.util.*;
                class Solution {
                	public static void main(String[] args) {
                		Scanner sc=new Scanner(System.in);
                		int t=sc.nextInt();
                		for(int test=1;test<=t;test++) {
                			String s=sc.next(),a="";
                			int numberCharsTaken;
                			int flag = 0,x=0;
                			for(numberCharsTaken = 1;numberCharsTaken<=s.length();numberCharsTaken++) {
                				a = s.substring(s.length() - numberCharsTaken);
                				for(x = a.length()-1;x>0;x--) {
                					if(a.charAt(0)<a.charAt(x)) {
                						flag = 1;
                						break;
                					}
                					if(flag == 1)
                						break;
                				}
                				if(flag == 1)
                					break;
                			}
                			if(flag == 1){
                				String temp = a.substring(0,x)+a.substring(x+1);
                				char c[] = temp.toCharArray();
                				Arrays.sort(c);
                				temp = a.charAt(x) + new String(c);
                				String ans = s.substring(0,s.length()-numberCharsTaken)+temp;
                				System.out.println(ans);	
                			}
                			else
                				System.out.println("no answer");
                		}
                	}
                }
                
                • + 1 comment

                  @shraiysh Can you explain the logic here. The lexicographical permutation solution didnt work for me. It is giving me runtime error. But your code is working for me. I dont understand why.

                  • + 0 comments

                    For me it threw a runtime error when I was not concidereing w.length = 1 cases.

            • + 0 comments

              It did not work. It stuck in line 20348

        • + 0 comments

          Scanner will work in these cases. I submitted using scanner. The problem must lie elsewhere.

        • + 0 comments

          thanks! that is what I needed. Don't really know why Scanner is slower than buffreader though.

      • + 1 comment

        Simple java solution : algorithm n wikipedia

        static String biggerIsGreater(String w) { char[] arr = w.toCharArray(); int i = arr.length - 1; // finding p --> i while(i>0 && arr[i-1]>=arr[i]){ i--; } if(i<=0){ //System.out.println("Pretty much last one!!"); return "no answer"; } int j = arr.length-1; while(arr[j]<= arr[i-1]){ j--; } char temp = arr[i-1]; arr[i-1] = arr[j]; arr[j] = temp;

            j = arr.length - 1;
            while(i<j)
            {
                char tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
                j--;
                i++;
            }
            String ret = new String(arr);
            return ret;
        }
        
        • + 1 comment

          this logic is to rev the string in O(n) time and O(1) space. can u explain, how this iis working?

          • + 0 comments

            its actually n/2

      • + 0 comments

        Use this to find no answer without solving:

        https://www.hackerrank.com/challenges/bigger-is-greater/forum/comments/595411

      • + 0 comments

        I am having the same TLE problem in test #1 and #2. Can someone help me out?

    • + 1 comment

      Too helpful! Thanxx! :-)

      • + 0 comments

        hey i have used the same logic and implemented this problem.however my code fails for test case 1 and 2 .can u please review my code and tell where the error lies?? i posted my code in the discussions forum.please have a look at the recent comments with my username.

    • + 0 comments

      Helped :)

    • + 0 comments

      Super helpful! Learned something new today!

    • + 0 comments

      Nice and clear explanation!

    • + 0 comments

      thanks!! that was well explained

    • + 0 comments

      Best Explanantion! Learned something new!

    • + 0 comments

      very helpful, thanks

    • + 0 comments

      Thank you. This was so helpful and very cool.

    • + 0 comments

      wow! great explanation ,Thanks

    • + 0 comments

      Thank You! Something new everyday.

    • + 0 comments

      That was really helpful!! Got to learn a lot..thanks :)

    • + 0 comments

      great

    • + 4 comments
      #include <cmath>
      #include <cstdio>
      #include <vector>
      #include <iostream>
      #include <algorithm>
      #include <limits.h>
      using namespace std;
      
      
      int main() {
          long long int t;
          cin>>t;
          while(t>0)
          {
              string s;
              cin>>s;
              string ss=s;
              int i=s.length()-1;
              int pivot;
              while(s[i-1]>=s[i]&&i>=0)
                  i--;
              if(i!=0)
                {
                  pivot=i-1;
                  int min=INT_MAX;
                  int index;
                  for(int j=i;j<s.length();j++)
                    {
                      if(int(s[j])>int(s[pivot])&&min>int(s[j])){
                          min=s[j];
                          index=j;
                      }
                  }
                 char temp=s[pivot];
                  s[pivot]=s[index];
                  s[index]=temp;
                  sort(s.begin()+i,s.end());
                  cout<<s<<endl;
              }
              else
                  cout<<"no answer\n";
               t--;    
          }
              
          return 0;
      }
      

      In my code,testcase 1 and testcase 2 are showing segmentation fault can you tell me what is the reason.I have used the same concept as described in article.

      • + 1 comment

        Hi,

        I have a confuse about this algorithm. In this tutorial, they said the suffix is 5 3 3 0 and the pivot is 2. After that, they said we can swap 2 with the smallest number, in the suffix that is greater than pivot. I misunderstood in here why 0 1 3 is the minimize prefix? In my opinion, 0 1 0 is the minimum prefix, right? Could you guys explain that point for me please. Thanks

        • + 1 comment

          Hi, the pivot should be smaller than the number you are swapping with, otherwise the final sequence would be lexicographically smaller than the original. So, we are finding the smallest number in the suffix, greater than the pivot, which is 3 in the tutorial. Hope that helped.

          • + 1 comment

            Thanks for answering me. So, I just want to confirm that the next sequence has to be the smallest one, but it has to be bigger than the original one, right?

            • + 0 comments

              Yes, exactly.

      • + 0 comments

        In your first while loop you are using condition i>=0, which results in i=-1 if its already sorted string. So your next condition becomes s[-1]<=s[0] which is resulting in segementation fault.

      • + 0 comments

        Hmm, I looked at your code, and incase you havent figured it out yet, you get segmentation fault beacuse you are accessing s[i-1] when i is 0; Check for this and fix it to get rid of segmentation fault

      • + 0 comments

        I was having the same problem....I found the error to be in the provided code (not the first time). Try adding a "free(w);" at the end of the loop in main. The sandbox was running out of memory!

    • + 0 comments

      Guys think about the logic for a few minutes before looking at this!

    • + 0 comments

      Great Tutorial

    • + 0 comments

      extremely helpful! thanks a lot!

    • + 0 comments

      thank you very much

    • + 1 comment

      I tried to implement same algorithm. But only got test0 and test3 successful. I have written following code. Where might I be wrong?

      public static void main(String[] args) throws IOException{
          BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
          int n = Integer.parseInt(br.readLine());
          String[] str = new String[n];
          for (int i =0; i<n;i++){
              str[i]=br.readLine();
          }
          //int n=6;
          //String[] str = {"ab","bb","hefg","dhck","dkhc","zzzayybbaa"};
          List<String> pLst=new ArrayList<String>();
          for(String s:str){
              char[] chars = s.toCharArray();
              List<Character> lst =toChList(chars);
              pLst.add(listToString(nextBigPerm(lst)));
          }
          for(int i=0;i<str.length;i++){
              System.out.println((pLst.get(i).equals(str[i]) || str[i].length()<2)?"no answer":pLst.get(i));
          }
      }
      private static List<Character> toChList(char[] chars){
          List<Character> ch = new ArrayList<Character>();
          for (char c: chars)
              ch.add(c);
          return ch;
      }
      private static List<Character> nextBigPerm(List<Character> lst){
          int pivot = 0;
          int swap = lst.size() - 1;
          if (swap ==0) return lst;
          for(int i=1;i<lst.size();i++){
              if (lst.get(i-1)<lst.get(i))
                  pivot=i-1;
              if (lst.get(pivot)<lst.get(i))
                  swap = i;
          }
          Collections.swap(lst,pivot,swap);
          Collections.sort(lst.subList(pivot+1,lst.size()));
          return lst;
      }
      private static String listToString(List<Character> lst){
          StringBuilder s = new StringBuilder();
          for(Character c:lst)
              s.append(c);
          return s.toString();
      }
      
      • + 0 comments

        Try checking is the next permutated string is actually greater than the original string or not. Try if(next_str.equals(str)||next_str.compareTo(str)<1)System.out.println("no answer"); permutated string=next_str original=string Now if the permutated string compareTo original string is smaller then print "no answer" because it is actually smaller than the original string. It happens when pivot=swap=0 means rest of the characters are already smaller.

    • + 0 comments

      Thanks @devstarj this http://www.nayuki.io/page/next-lexicographical-permutation-algorithm could be posted in the topics for Java solution

    • + 0 comments

      Awesome! Love the hackerrank community.

    • + 0 comments

      very nice

    • + 0 comments

      Thanks it was very helpful

    • + 0 comments

      I love you

    • + 0 comments

      Thank you ...

    • + 0 comments

      Thanks for the logic! Great help.

    • + 3 comments
      for _ in range(int(input())):
          s = input()
          has_greater = False
          for i in range(len(s)-1)[::-1]:
              if ord(s[i]) < ord(s[i+1]):
                  for j in range(i+1,len(s))[::-1]:
                      if ord(s[i]) < ord(s[j]):
                          lis = list(s)
                          lis[i],lis[j]=lis[j],lis[i]
                          print("".join(lis[:i+1]+lis[i+1:][::-1]))
                          has_greater = True
                      if has_greater == True:
                          break
              if has_greater == True:
                  break
          if has_greater == False:
              print("no answer")
      

      thanks for posting this algorithm. here's a python 3 solution based on this algorithm

      • + 0 comments

        no need check ord(s[i]) < ord(s[j]), just s[i] < s[j] is enough.

      • + 4 comments

        this code like in C

        Would rather use more Pythonic style, for example:

        def biggerIsGreater(s):

        for i in range(len(s)-1)[::-1]:
            if s[i] < s[i+1]:
                for j in range(i+1,len(s))[::-1]:
                    if s[i] < s[j]:
                        lis = list(s) 
                        lis[i],lis[j]=lis[j],lis[i]
                        return "".join(lis[:i+1]+lis[i+1:][::-1])
        return 'no answer'
        
        • + 1 comment

          what [ : : -1] it does after range() ??

          • + 1 comment

            it reverse the range.

            • + 0 comments

              Got it, thanks.

        • + 0 comments

          how u develop that level of thinking

        • + 1 comment

          My Python3 code is similar to the above two code snippets. However, it doesn't use any auxiliary list lis. The purpose of my updates I,J are to find the furthest starting index of modification; for example, if w="acdb", then J=1 and I=2, to get "adbc" not "bacd".

          def biggerIsGreater(w):
          
              J = -1
              for i in range( len(w)-1, 0, -1 ):
                  for j in range( i-1, J, -1 ):
                      if w[i] > w[j] : I,J = i,j ; break
              if J == -1 : return "no answer"
              return w[:J]+w[I]+''.join(sorted(w[J:I]+w[I+1:]))
          
          • + 1 comment

            i tried same solution, test cases are failng

            • + 0 comments

              You must have mistyped; carefully check again as an eye for detail is one of many marks of a good programmer. A fresh copy-and-paste into HackerRank, as I just did now with my own code, worked. Upvote if you like the code and ideas behind it, which I leave to users to catch up as mental exercise.

    • + 1 comment

      this is a hell of a lot simpler then the nayuki page

      http://stackoverflow.com/questions/1622532/algorithm-to-find-next-greater-permutation-of-a-given-string

    • + 0 comments

      Thanks a Lot.I didnt think that it is this much simple

    • + 0 comments

      Learnt new logic. Very helpful. Thanks!

    • + 0 comments

      That moment when your inital algorithm was exactly the same

    • + 0 comments

      Thank you so much.It really helped a lot.

    • + 0 comments

      Thank you so much!

      Also remember to include the edge case where the length of the word is 1.

    • + 0 comments

      yeah !!! that taught me the algo!! thanks!1

    • + 0 comments

      Thank you so much!

    • + 1 comment

      I think there is problem in the algorithm, instead of reversing the subarray , it should be sorted.

      • + 0 comments

        It's same with sorting. In algorith page it says :"Firstly, identify the longest suffix that is non-increasing (i.e. weakly decreasing)." And that's the part helped me to see my algorithm's mistake. I was just finding the pair to swap, then sorting second part. It was giving correct answers for only around 96 percent of words, then looking for alternative permutations was causing timeouts.

    • + 0 comments

      good job,better than editorial!

    • + 0 comments

      nice one

    • + 0 comments

      Thanks for the blog

    • + 0 comments

      thanks. copied this solution and refactored a little bit.

          static String biggerIsGreater(String w) {
              char[] chars = w.toCharArray();
              return nextPermutation(chars)
                  ? new String(chars)
                  : "no answer";
          }
          static boolean nextPermutation(char[] array) {
              int i = getLastPeakIndex(array);
              if (i <= 0) // like "dcba", no answer
                  return false;
      
              int j = getReplacementIndex(array, i - 1);
      
              swap(array, i-1, j);
      
              // Reverse the part on the right of i - 1 to make it as small as possible
              j = array.length - 1;
              while (i < j) {
                  swap(array, i, j);
                  i++;
                  j--;
              }
              
              return true;
          }
      
          static int getLastPeakIndex(char[] chars){
              int i = chars.length - 1;
              while (i > 0 && chars[i - 1] >= chars[i])
                  i--;
              return i;
          }
      
          static int getReplacementIndex(char[] chars, int givenIndex){
              int i = chars.length - 1;
              while (chars[i] <= chars[givenIndex])
                  i--;
              return i;
          }
      
          static void swap(char[] chars, int a, int b){
              chars[a] ^= chars[b];
              chars[b] ^= chars[a];
              chars[a] ^= chars[b];
          }
      
    • + 0 comments

      thanks bro!! helpful..

    • + 0 comments

      thank so much :))

    • + 0 comments

      Hi,

      I have created a tutorial for you all. have a look, i hope it will help you to solve the problem.

      Here is the video explanation of my solution in O(n) time -

      https://youtu.be/BMbeeB_57Pk

    • + 1 comment

      Here's my JS solution. I started from the end of the string and worked backwords until I found a character that is less than something previous:

          let a = `abcdefghijklmnopqrstuvwxyz`;
          let idVals = [[w.length-1, a.indexOf(w.charAt(w.length-1))]];
      
          for(let i = w.length-2; i >= 0; i--){
              let val = a.indexOf(w.charAt(i));
      
              if(val < idVals[idVals.length-1][1]){
                  let sub = ``;
      
                  for(let j = 0; j < idVals.length; j++){
                      let id = idVals[j][0];
      
                      if(val < idVals[j][1]){
                          let start = (i === 0) ? w.charAt(id) :
                          w.substring(0,i) + w.charAt(id);
                          sub += w.substring(i,id).split(``).sort().join(``);
                          console.log(sub);
      
                          return start + sub;
                      }
                      sub += w.charAt(id);
                  }
              }
              idVals.push([i,val]);
          }
          return `no answer`;
      
      • + 0 comments

        Please can you explain the solution?

    • + 0 comments

      Thanks great explanation

    • + 0 comments

      Very helpful article. Thanks!

    • + 0 comments

      very helpful.thanks!

    • + 0 comments

      Great solution!!!! I was trying from last two days and finally found this ..thanks!

    • + 0 comments

      nice one!

    • + 1 comment

      int main() { int t; cin >> t; while(t--) { string w; cin >> w;

          if(next_permutation(w.begin(),w.end())==0)
          cout << "no answer " << endl;
          else
          cout << w << endl;
      }
      return 0;
      

      }

      • + 1 comment

        can you explain why you took (next_permutation ==0) and what will happen with that condition

        • + 0 comments

          because it returns 0 or false if the function cannot make the bigger string in lexicographically order. for example string = "DCBA" -> this is the biggest and the function will return 0, otherwise it will returns 1 or true. But the function always change the order to the smallest if the string was the biggest

    • + 0 comments

      I would suggest all to have a look at this article instead of looking for code in the disscussion. The approach in the article is readily comprehensible and decipherable.

    • + 0 comments

      This one is great.

    • + 0 comments

      really thanks for this man ... I really needed this next_permutation raw logic..

    • + 0 comments

      Very well explained by the person in the link above.

      Thanks for sharing!!

    • + 0 comments

      cool. thanks man. I've been doing this exercise for two days..

    • + 0 comments

      this is a very good explanation!

    • + 0 comments

      here is my solution in JAVASCRIPT :

      HackerRank Bigger is Greater problem solution

    • + 0 comments

      *Hi , I have done the problem through the following code. Can anyone explain me where I commited the mistake *

      I appreciate your help

      thanks in advance

        	fun biggerIsGreater(w: String): String {
          for (i in w.length-1 downTo 1){
              for( j in i-1 downTo 0){
                  if(w[i]>w[j]){
                      val result = w.toCharArray()
                      val temp = result[i]
                      result[i]=result[j]
                      result[j]=temp
                      return  String(result).substring(0,j+1) + String(result).substring(j+1,w.length).reversed()
                  }
              }
          }    
          return "no answer"
      
      }
      
    • + 0 comments

      Thanks a lot!

    • + 0 comments

      Is there mistake in code?? We should do : arr[j] >= arr[i-1] for j>=i but in code they did : arr[j] <= arr[j-1]? why ? is this incorrect or am I missing something?

    • + 0 comments

      thank you so much i was missing the last sorted suffix part

    • + 0 comments

      Brilliant. Thanks!