Cho một số, tìm số cao hơn tiếp theo có cùng bộ chữ số chính xác với số ban đầu


226

Tôi vừa đánh bom một cuộc phỏng vấn và không đạt được nhiều tiến bộ trong câu hỏi phỏng vấn của mình. Bất cứ ai có thể cho tôi biết làm thế nào để làm điều này? Tôi đã thử tìm kiếm trực tuyến nhưng không thể tìm thấy bất cứ điều gì:

Cho một số, tìm số cao hơn tiếp theo có cùng bộ chữ số chính xác với số ban đầu. Ví dụ: đã cho 38276 trả lại 38627

Tôi muốn bắt đầu bằng cách tìm chỉ số của chữ số đầu tiên (từ bên phải) nhỏ hơn chữ số. Sau đó, tôi sẽ xoay các chữ số cuối cùng trong tập hợp con sao cho nó là số lớn nhất tiếp theo bao gồm các chữ số tương tự, nhưng bị kẹt.

Người phỏng vấn cũng đề nghị cố gắng hoán đổi từng chữ số một, nhưng tôi không thể tìm ra thuật toán và chỉ nhìn chằm chằm vào màn hình trong khoảng 20-30 phút. Không cần phải nói, tôi nghĩ rằng tôi sẽ phải tiếp tục săn việc.

chỉnh sửa: vì giá trị của nó, tôi đã được mời đến vòng phỏng vấn tiếp theo


15
không cần suy nghĩ về nó quá nhiều, một sự khởi đầu ít nhất sẽ là sức mạnh vũ phu tính toán tất cả các hoán vị của các chữ số và lấy số tối thiểu lớn hơn số đầu vào
BrokenGlass

13
trong C ++, bạn chỉ có thể sử dụng next_permutation;-)
thedayturns

9
FYI, đây là cách tôi giải quyết trong khoảng 15 phút trong khi thậm chí không nghĩ về vấn đề: Lần đầu tiên tôi dành 5 phút để viết một thuật toán vũ phu chỉ tạo ra tất cả các hoán vị có thể có của một tập hợp các chữ số, sắp xếp chúng và hiển thị chúng. Tôi đã dành 5 phút để xem qua dữ liệu đó cho đến khi một mô hình xuất hiện từ danh sách (giải pháp được chấp nhận O (n) ở đây trở nên rõ ràng chỉ sau một thời gian ngắn tìm kiếm), sau đó tôi đã dành 5 phút để mã hóa thuật toán O (n).
Ben Lee

1
Nói chung, đây không phải là một cách tồi để đưa ra các thuật toán để giải quyết loại vấn đề này khi bạn bị mắc kẹt - sử dụng sức mạnh vũ phu trên một số mẫu nhỏ để tạo ra nhiều dữ liệu mà sau đó bạn có thể sử dụng để xem các mẫu dễ dàng hơn.
Ben Lee

19
Tôi cũng muốn chỉ ra rằng, nếu bạn thực sự không thể tìm ra một cách hiệu quả để làm điều này, thì không có gì là chắc chắn để thất bại trong cuộc phỏng vấn (và trong thế giới kinh doanh, đó là một cách chắc chắn để bỏ lỡ thời hạn sản phẩm) . Khi bạn gặp khó khăn, thay vì từ bỏ, bạn nên bắt buộc và đưa một nhận xét lên hàng đầu "TODO: refactor cho hiệu suất" hoặc đại loại như thế. Nếu tôi đang phỏng vấn và ai đó đã làm điều đó, tôi sẽ không nhất thiết phải thất bại. Ít nhất họ đã nghĩ ra thứ gì đó hoạt động VÀ nhận ra rằng có thứ gì đó tốt hơn ở ngoài đó, ngay cả khi họ không thể tìm thấy nó.
Ben Lee

Câu trả lời:


272

Bạn có thể làm điều đó trong O(n)( nsố chữ số) như thế này:

Bắt đầu từ bên phải, bạn tìm thấy cặp chữ số đầu tiên sao cho chữ số bên trái nhỏ hơn chữ số bên phải. Hãy tham khảo chữ số bên trái của "chữ số-x". Tìm số nhỏ nhất lớn hơn chữ số-x ở bên phải chữ số-x và đặt ngay bên trái chữ số-x. Cuối cùng, sắp xếp các chữ số còn lại theo thứ tự tăng dần - vì chúng đã theo thứ tự giảm dần , tất cả những gì bạn cần làm là đảo ngược chúng (lưu cho chữ số-x, có thể được đặt ở vị trí chính xác trong O(n)) .

Một ví dụ sẽ làm cho điều này rõ ràng hơn:

123456784987654321
bắt đầu bằng một con số

123456784 987654321
         ^ vị trí đầu tiên từ bên phải nơi chữ số bên trái nhỏ hơn bên phải  
         Chữ số "x" là 4

123456784 987654321
              ^ tìm chữ số nhỏ nhất lớn hơn 4 ở bên phải

123456785 4 98764321
        ^ đặt nó ở bên trái của 4

123456785 4 12346789
123456785123446789
         ^ sắp xếp các chữ số ở bên phải của 5. Vì tất cả chúng ngoại trừ 
         '4' đã được sắp xếp theo thứ tự giảm dần, tất cả những gì chúng ta cần làm là 
         đảo ngược thứ tự của họ và tìm vị trí chính xác cho '4'

Bằng chứng về sự đúng đắn:

Chúng ta hãy sử dụng chữ in hoa để xác định chuỗi chữ số và chữ thường cho chữ số. Cú pháp ABcó nghĩa là "nối chuỗi AB" . <là thứ tự từ điển, giống như thứ tự số nguyên khi các chuỗi chữ số có độ dài bằng nhau.

Số N ban đầu của chúng tôi có dạng AxB, trong đó xlà một chữ số duy nhất và Bđược sắp xếp giảm dần.
Số được tìm thấy bởi thuật toán của chúng tôi AyC, trong đó y ∈ Blà chữ số nhỏ nhất > x (nó phải tồn tại do cách xđã được chọn, xem ở trên)Cđược sắp xếp tăng dần.

Giả sử có một số số (sử dụng cùng một chữ số) N'sao cho AxB < N' < AyC. N'phải bắt đầu bằng Anếu không nó không thể nằm giữa chúng, vì vậy chúng ta có thể viết nó dưới dạng AzD. Bây giờ bất đẳng thức của chúng ta là AxB < AzD < AyC, tương đương với xB < zD < yCnơi cả ba chuỗi chữ số chứa cùng một chữ số.

Để điều đó trở thành sự thật, chúng ta phải có x <= z <= y. Vì ylà chữ số nhỏ nhất > x, zkhông thể nằm giữa chúng, vì vậy z = xhoặc z = y. Nói z = x. Khi đó bất đẳng thức của chúng ta là xB < xD < yC, có nghĩa là B < Dcả hai BDcó cùng một chữ số. Tuy nhiên, B là giảm dần sắp xếp, do đó không có chuỗi với những chữ số lớn hơn nó. Vì vậy, chúng ta không thể có B < D. Thực hiện theo các bước tương tự, chúng tôi thấy rằng nếu z = y, chúng tôi không thể có D < C.

Do đó N'không thể tồn tại, có nghĩa là thuật toán của chúng tôi tìm đúng số lớn nhất tiếp theo.


7
giải pháp tốt đẹp! có một câu hỏi nói "chữ số nhỏ nhất lớn hơn x" là y. chúng ta có thể hoán đổi x và y, sau đó đảo ngược x.index + 1 -> end không?
Kent

8
Điều gì xảy ra với số 99999?
Sterex

19
@Sterex, nó không chỉ 99999; bất kỳ số nào có chữ số đã được sắp xếp đầy đủ theo thứ tự giảm dần là tối đa (vì vậy 98765 cũng không có giải pháp nào). Điều này rất dễ phát hiện theo chương trình vì bước 1 của thuật toán sẽ thất bại (không có cặp chữ số liên tiếp nào sao cho "chữ số bên trái nhỏ hơn chữ số bên phải").
Ben Lee

3
@TMN: 9 lớn hơn 8, vì vậy bạn sẽ di chuyển 9 sang trái 8: 9 832sau đó sắp xếp mọi thứ ở bên phải của 9:9238
BlueRaja - Danny Pflughoeft 22/212

4
@Kent để giải pháp của bạn hoạt động, bạn sẽ phải thay đổi tìm chữ số nhỏ nhất lớn hơn 4 sang phải để tìm chữ số nhỏ nhất lớn hơn 4 từ bên phải . Mặt khác, ví dụ, 1234567849876 55 4321 sẽ dẫn đến 1234567851234 54 6789 (thay vì 1234567851234 45 6789). Một nitpick :-)
osundblad

94

Một vấn đề gần như giống hệt nhau xuất hiện dưới dạng sự cố Code Jam và có một giải pháp tại đây:

http://code.google.com.vn/codejam/contest/dashboard?c=186264#s=a&a=1

Dưới đây là tóm tắt về phương pháp sử dụng một ví dụ:

34722641

A. Chia chuỗi các chữ số thành hai, sao cho phần bên phải càng dài càng tốt trong khi còn lại theo thứ tự giảm dần:

34722 641

(Nếu toàn bộ số theo thứ tự giảm dần, sẽ không có số nào lớn hơn được thực hiện mà không thêm chữ số.)

B.1. Chọn chữ số cuối cùng của dãy đầu tiên:

3472(2) 641

B.2. Tìm chữ số nhỏ nhất trong dãy thứ hai lớn hơn nó:

3472(2) 6(4)1

B.3. Trao đổi chúng:

3472(2) 6(4)1
->
3472(4) 6(2)1
->
34724 621

C. Sắp xếp chuỗi thứ hai theo thứ tự tăng dần:

34724 126

D. Xong rồi!

34724126

1
Typo ở đó: Tôi nghĩ "-> 34721 621" nên là "-> 34724 621"?
bjnord

1
@bjnord Bắt tốt. Đã sửa. Không chắc chắn làm thế nào tôi quản lý điều đó - nó đã đúng trong các dòng tiếp theo.
Weeble

+1 Câu trả lời hay nhất tại đây. Trực quan và nhanh chóng. (đó cũng là người tôi nghĩ đến khi tôi viết bài này ra giấy;))
Muhd

1
@Neel - Ở bước C, các chữ số chúng ta muốn sắp xếp theo thứ tự giảm dần, ngoại trừ chữ số chúng ta đã hoán đổi ở bước B. Để sắp xếp chúng, chúng ta thực sự chỉ cần đảo ngược chúng và đưa chữ số hoán đổi vào đúng vị trí. Đây là những gì BlueRaja mô tả.
Weeble

1
@Dhavaldave Vấn đề là gì? Ở bước A, bạn nhận được "12" và "3". Ở bước B, bạn nhận được "13" và "2". Ở bước C không có gì thay đổi. Ở bước D, bạn nhận được "132". Trường hợp duy nhất mà bạn sẽ không nhận được câu trả lời là khi số đó đã là mức tối đa có thể, ví dụ: "321". Trong trường hợp đó, bước A cung cấp cho bạn "" và "321" và bạn không thể tiến hành một chuỗi trống cho phía bên trái của phần tách.
Weeble

14

Đây là một giải pháp nhỏ gọn (nhưng một phần vũ phu) trong Python

def findnext(ii): return min(v for v in (int("".join(x)) for x in
    itertools.permutations(str(ii))) if v>ii)

Trong C ++, bạn có thể thực hiện các hoán vị như thế này: https://stackoverflow.com/a/9243091/1149664 (Đó là thuật toán tương tự như thuật toán trong itertools)

Đây là một triển khai của câu trả lời hàng đầu được mô tả bởi Weeble và BlueRaja, (các câu trả lời khác). Tôi nghi ngờ có bất cứ điều gì tốt hơn.

def findnext(ii):
    iis=list(map(int,str(ii)))
    for i in reversed(range(len(iis))):
        if i == 0: return ii
        if iis[i] > iis[i-1] :
            break        
    left,right=iis[:i],iis[i:]
    for k in reversed(range(len(right))):
        if right[k]>left[-1]:
           right[k],left[-1]=left[-1],right[k]
           break
    return int("".join(map(str,(left+sorted(right)))))

Bất kỳ cơ hội mà bất cứ ai có thể cập nhật điều này xin vui lòng? Dường như không hoạt động trong Python 3 như nó hiển thị type 'map' has no len(). Tôi chỉ cần thay đổi dòng thứ 2 thành iis=list(map(int,str(ii))). Và bất cứ ai có thể giải thích các if i == 0: return iidòng xin vui lòng? Tại sao nó hoạt động với đầu vào như 111 hoặc 531? Cảm ơn.
Bowen Liu

Bây giờ tôi đã sửa nó cho python 3 bằng cách thêm listlist () vào iis = .... Các trường hợp 111 và 531 không có giải pháp nhưng việc thực hiện của tôi trả về 111 và 531 cho các trường hợp đó. Bạn có thể thay đổi điều đó thành một ngoại lệ của những gì bạn tìm thấy là tốt hơn bằng cách thay đổi dòng i == 0 đó.
Johan Lundberg

Cảm ơn. Tôi thực sự lặp theo hướng khác vì vậy tôi đã bị nhầm lẫn bởi i == 0, trong khi trong tình huống của tôi thì nó sẽ như vậy i == len(iis).
Bowen Liu

8

Tối thiểu, đây là một vài ví dụ về các giải pháp dựa trên Chuỗi sức mạnh vũ phu, mà bạn đáng lẽ có thể đưa ra ngay trên đỉnh đầu của mình:

danh sách các chữ số được 38276sắp xếp là23678

danh sách các chữ số được 38627sắp xếp là23678

gia tăng lực lượng, sắp xếp và so sánh

Dọc theo các giải pháp lực lượng vũ phu sẽ được chuyển đổi thành Chuỗi và lực lượng vũ phu tất cả các số có thể sử dụng các chữ số đó.

Tạo ints từ tất cả chúng, đặt chúng vào một danh sách và sắp xếp nó, nhận mục tiếp theo sau mục tiêu.

Nếu bạn dành 30 phút cho việc này và ít nhất không nghĩ ra ít nhất một cách tiếp cận vũ phu, tôi cũng sẽ không thuê bạn.

Trong thế giới kinh doanh, một giải pháp không phù hợp, chậm chạp và cồng kềnh nhưng hoàn thành công việc luôn có giá trị hơn bất kỳ giải pháp nào, thực tế là khá nhiều mô tả tất cả các phần mềm kinh doanh, không linh hoạt, chậm chạp và cồng kềnh.


1
Vâng, nhận xét đầu tiên của tôi về con dơi là "Tôi có thể vũ phu nhưng ...". Nếu thực sự không phải là một giải pháp thuật toán, tôi sẽ thất vọng
bhan

4
Nếu tôi là người phỏng vấn, tôi sẽ không hạnh phúc với cách tiếp cận vũ phu.
Ahmad Y. Saleh

@benjamin han, có giải pháp thuật toán. Chỉ cần giữ các chữ số thay đổi bắt đầu từ bên phải, cho đến khi bạn tìm thấy kết quả. Không cần phải tính toán tất cả permutatnios trước đây.
đan điền

7
Chắc chắn có nhiều giải pháp tốt hơn nhiều so với lực lượng vũ phu, ví dụ ardendertat.com/2012/01/02/ trên
BrokenGlass

@BrokenGlass Chắc chắn là một giải pháp tốt hơn nhiều. Tôi chỉ nghĩ ra ý tưởng đó và sau đó bạn đăng thuật toán.
Onit

5
function foo(num){
 sortOld = num.toString().split("").sort().join('');
 do{
    num++;
   sortNew = num.toString().split("").sort().join('');
 }while(sortNew!==sortOld);
 return num;
}

Tôi đã đưa ra giải pháp này. Xin vui lòng nếu bạn có bất kỳ câu hỏi, xin hỏi.
Ashikodi

4

Ý tưởng của bạn

Tôi muốn bắt đầu bằng cách tìm chỉ số của chữ số đầu tiên (từ bên phải) nhỏ hơn chữ số. Sau đó, tôi sẽ xoay các chữ số cuối cùng trong tập hợp con sao cho nó là số lớn nhất tiếp theo bao gồm các chữ số tương tự, nhưng bị kẹt.

là khá tốt, thực sự. Bạn chỉ cần xem xét không chỉ chữ số cuối cùng mà tất cả các chữ số có ý nghĩa ít hơn so với hiện tại được xem xét. Vì trước khi đạt được, chúng ta có một chuỗi các chữ số đơn điệu, đó là chữ số ngoài cùng bên phải nhỏ hơn chữ số bên phải của nó. Trân trọng

1234675
    ^

Số lớn hơn tiếp theo có cùng chữ số là

1234756

Chữ số tìm thấy được trao đổi cho chữ số cuối cùng - nhỏ nhất trong số các chữ số được xem xét - và các chữ số còn lại được sắp xếp theo thứ tự tăng dần.


4

Tôi khá chắc chắn rằng người phỏng vấn của bạn đang cố gắng đẩy bạn nhẹ nhàng về phía như thế này:

local number = 564321;

function split(str)
    local t = {};
    for i = 1, string.len(str) do
        table.insert(t, str.sub(str,i,i));
    end
    return t;
end

local res = number;
local i = 1;
while number >= res do
    local t = split(tostring(res));
    if i == 1 then
        i = #t;
    end
    t[i], t[i-1] = t[i-1], t[i];
    i = i - 1;
    res = tonumber(table.concat(t));
end

print(res);

Không nhất thiết là giải pháp hiệu quả hoặc thanh lịch nhất nhưng nó giải quyết ví dụ được cung cấp theo hai chu kỳ và hoán đổi các chữ số một lần như ông đề xuất.


2

Lấy một số và chia nó thành chữ số. Vì vậy, nếu chúng ta có một số gồm 5 chữ số, chúng ta có 5 chữ số: abcde

Bây giờ trao đổi d và e và so sánh với số ban đầu, nếu nó lớn hơn, bạn có câu trả lời của mình.

Nếu nó không lớn hơn, trao đổi e và c. Bây giờ so sánh và nếu nó là hoán đổi nhỏ hơn d và e một lần nữa (chú ý đệ quy), lấy nhỏ nhất.

Thực hiện thông qua cho đến khi bạn tìm thấy một số lượng lớn hơn. Với đệ quy, nó sẽ hoạt động như khoảng 9 dòng lược đồ, hoặc 20 của c #.


2

Đó là câu hỏi rất thú vị.

Đây là phiên bản java của tôi. Mất khoảng 3 giờ để tôi tìm ra mô hình để hoàn thành mã trước khi tôi kiểm tra ý kiến ​​của những người đóng góp khác. Vui mừng khi thấy ý tưởng của tôi khá giống với những người khác.

Dung dịch O (n). Thành thật mà nói, tôi sẽ thất bại trong cuộc phỏng vấn này nếu thời gian chỉ là 15 phút và yêu cầu hoàn thành mã hoàn thành trên bảng trắng.

Dưới đây là một số điểm thú vị cho giải pháp của tôi:

  • Tránh bất kỳ phân loại.
  • Tránh hoàn toàn hoạt động chuỗi
  • Đạt được độ phức tạp không gian O (logN)

Tôi đặt bình luận chi tiết trong mã của tôi và Big O trong mỗi bước.

  public int findNextBiggestNumber(int input  )   {
    //take 1358642 as input for example.
    //Step 1: split the whole number to a list for individual digital   1358642->[2,4,6,8,5,3,1]
    // this step is O(n)
    int digitalLevel=input;

    List<Integer> orgNumbersList=new ArrayList<Integer>()   ;

    do {
        Integer nInt = new Integer(digitalLevel % 10);
        orgNumbersList.add(nInt);

        digitalLevel=(int) (digitalLevel/10  )  ;


    } while( digitalLevel >0)    ;
    int len= orgNumbersList.size();
    int [] orgNumbers=new int[len]  ;
    for(int i=0;i<len;i++){
        orgNumbers[i ]  =  orgNumbersList.get(i).intValue();
    }
    //step 2 find the first digital less than the digital right to it
    // this step is O(n)


    int firstLessPointer=1;
    while(firstLessPointer<len&&(orgNumbers[firstLessPointer]>orgNumbers[ firstLessPointer-1 ])){
        firstLessPointer++;
    }
     if(firstLessPointer==len-1&&orgNumbers[len-1]>=orgNumbers[len-2]){
         //all number is in sorted order like 4321, no answer for it, return original
         return input;
     }

    //when step 2 step finished, firstLessPointer  pointing to number 5

     //step 3 fristLessPointer found, need to find  to  first number less than it  from low digital in the number
    //This step is O(n)
    int justBiggerPointer=  0 ;

    while(justBiggerPointer<firstLessPointer&& orgNumbers[justBiggerPointer]<orgNumbers[firstLessPointer]){
        justBiggerPointer++;
    }
    //when step 3 finished, justBiggerPointer  pointing to 6

    //step 4 swap the elements  of justBiggerPointer and firstLessPointer .
    // This  is O(1) operation   for swap

   int tmp=  orgNumbers[firstLessPointer] ;

    orgNumbers[firstLessPointer]=  orgNumbers[justBiggerPointer]  ;
     orgNumbers[justBiggerPointer]=tmp ;


     // when step 4 finished, the list looks like        [2,4,5,8,6,3,1]    the digital in the list before
     // firstLessPointer is already sorted in our previous operation
     // we can return result from this list  but  in a differrent way
    int result=0;
    int i=0;
    int lowPointer=firstLessPointer;
    //the following pick number from list from  the position just before firstLessPointer, here is 8 -> 5 -> 4 -> 2
    //This Operation is O(n)
    while(lowPointer>0)        {
        result+= orgNumbers[--lowPointer]* Math.pow(10,i);
        i++;
    }
    //the following pick number from list   from position firstLessPointer
    //This Operation is O(n)
    while(firstLessPointer<len)        {
        result+= orgNumbers[firstLessPointer++ ]* Math.pow(10,i);
        i++;
    }
     return  result;

}

Đây là kết quả đang chạy trong Intellj:

959879532-->959892357
1358642-->1362458
1234567-->1234576
77654321-->77654321
38276-->38627
47-->74

Trong trường hợp 123, câu trả lời sẽ là gì? Thực tế, mã của bạn sẽ không tạo ra đầu ra trong khi nó sẽ xuất hiện 132
Dhaval dave

2

Một triển khai javascript của thuật toán @ BlueRaja.

var Bar = function(num){ 
  num = num.toString();
  var max = 0;
  for(var i=num.length-2; i>0; i--){
    var numArray = num.substr(i).split("");
    max = Math.max.apply(Math,numArray);
    if(numArray[0]<max){
        numArray.sort(function(a,b){return a-b;});
        numArray.splice(-1);
        numArray = numArray.join("");
        return Number(num.substr(0,i)+max+numArray);
    }
  }
  return -1;
};

1

Một giải pháp (bằng Java) có thể là như sau (Tôi chắc chắn bạn bè ở đây có thể tìm thấy tốt hơn):
Bắt đầu hoán đổi các chữ số từ cuối chuỗi cho đến khi bạn nhận được số cao hơn.
Tức là đầu tiên bắt đầu di chuyển lên chữ số thấp hơn. Sau đó, cao hơn tiếp theo vv cho đến khi bạn đạt mức cao hơn tiếp theo.
Sau đó sắp xếp phần còn lại. Trong ví dụ của bạn, bạn sẽ nhận được:

38276 --> 38267 (smaller) --> 38627 Found it    
    ^        ^                  ^        

 public static int nextDigit(int number){
    String num = String.valueOf(number);        
    int stop = 0;       
    char [] chars = null;
    outer:
        for(int i = num.length() - 1; i > 0; i--){          
            chars = num.toCharArray();
            for(int j = i; j > 0; j--){
                char temp = chars[j];
                chars[j] = chars[j - 1];
                chars[j - 1] = temp;
                if(Integer.valueOf(new String(chars)) > number){
                    stop = j;                   
                    break outer;                                
                }               
            }               
        }

    Arrays.sort(chars, stop, chars.length); 
    return Integer.valueOf(new String(chars));
}

@yi_H: Đầu ra là 63872. Tại sao, nó phải là gì?
Cratylus

tốt .. số cao hơn tiếp theo? :) đó là yêu cầu, phải không?
Karoly Horvath

@BlueRaja - Daniel Pflughoeft: Cảm ơn sự giúp đỡ của bạn. Tôi đã thay đổi mã như sau: Di chuyển số trả trước ít nhất (bao giờ mang lại số cao hơn) và sắp xếp phần còn lại
Cratylus

1

Nếu bạn đang lập trình trong C ++, bạn có thể sử dụng next_permutation:

#include <algorithm>
#include <string>
#include <iostream>

int main(int argc, char **argv) {
  using namespace std; 
   string x;
   while (cin >> x) {
    cout << x << " -> ";
    next_permutation(x.begin(),x.end());
    cout << x << "\n";
  }
  return 0;
}

Điều gì xảy ra nếu tôi nhập 100? :-)
jweyrich

1

Tôi không biết gì về thuật toán vũ phu khi trả lời câu hỏi này, vì vậy tôi đã tiếp cận nó từ một góc độ khác. Tôi quyết định tìm kiếm toàn bộ các giải pháp khả thi mà số này có thể được sắp xếp lại, bắt đầu từ số_given + 1 cho đến số tối đa có sẵn (999 cho số có 3 chữ số, 9999 cho 4 chữ số, v.v.). Tôi đã làm điều này giống như tìm một bảng màu với các từ, bằng cách sắp xếp số của từng giải pháp và so sánh nó với số được sắp xếp đưa ra làm tham số. Sau đó tôi chỉ đơn giản trả về giải pháp đầu tiên trong mảng các giải pháp, vì đây sẽ là giá trị có thể tiếp theo.

Đây là mã của tôi trong Ruby:

def PermutationStep(num)

    a = []
    (num.to_s.length).times { a.push("9") }
    max_num = a.join('').to_i
    verify = num.to_s.split('').sort
    matches = ((num+1)..max_num).select {|n| n.to_s.split('').sort == verify }

    if matches.length < 1
      return -1
    else
      matches[0]
    end
end

độ phức tạp thời gian của giải pháp này là gì?
Nitish Upreti

@ Myth17 Tôi không chắc, vì tôi chưa bao giờ thử nghiệm nó. Nếu bạn muốn tìm hiểu điều đó, hãy xem bài đăng này: stackoverflow.com/questions/9958299/ mẹo
Jeremiah McCurdy

1

Mã PHP

function NextHigherNumber($num1){
$num = strval($num1);
$max = 0;
for($i=(strlen($num)-2); $i>=0; $i--){
    $numArrayRaw = substr($num, $i);
    $numArray = str_split($numArrayRaw);
    $max = max($numArray);
    if ($numArray[0] < $max){
        sort( $numArray, SORT_NUMERIC );
        array_pop($numArray);
        $numarrstr = implode("",$numArray);
        $rt = substr($num,0,$i) . $max . $numarrstr;
        return $rt;
    }
}
return "-1";
}
echo NextHigherNumber(123);

0

Tôi chỉ thử nghiệm điều này với hai số. Họ đã làm. Là Giám đốc CNTT trong 8 năm cho đến khi nghỉ hưu vào tháng 12 năm ngoái, tôi quan tâm đến ba điều: 1) Độ chính xác: thật tốt nếu nó hoạt động - luôn luôn. 2) Tốc độ: phải được người dùng chấp nhận. 3) Rõ ràng: Tôi có thể không thông minh như bạn, nhưng tôi đang trả tiền cho bạn. Hãy chắc chắn rằng bạn giải thích những gì bạn đang làm, bằng tiếng Anh.

Omar, tốt nhất của may mắn đi về phía trước.

Sub Main()

Dim Base(0 To 9) As Long
Dim Test(0 To 9) As Long

Dim i As Long
Dim j As Long
Dim k As Long
Dim ctr As Long

Const x As Long = 776914648
Dim y As Long
Dim z As Long

Dim flag As Boolean

' Store the digit count for the original number in the Base vector.
    For i = 0 To 9
        ctr = 0
        For j = 1 To Len(CStr(x))
            If Mid$(CStr(x), j, 1) = i Then ctr = ctr + 1
        Next j
        Base(i) = ctr
    Next i

' Start comparing from the next highest number.
    y = x + 1
    Do

' Store the digit count for the each new number in the Test vector.
        flag = False
        For i = 0 To 9
            ctr = 0
            For j = 1 To Len(CStr(y))
                If Mid$(CStr(y), j, 1) = i Then ctr = ctr + 1
            Next j
            Test(i) = ctr
        Next i

' Compare the digit counts.
        For k = 0 To 9
            If Test(k) <> Base(k) Then flag = True
        Next k

' If no match, INC and repeat.
        If flag = True Then
            y = y + 1
            Erase Test()
        Else
            z = y ' Match.
        End If

    Loop Until z > 0

    MsgBox (z), , "Solution"

End Sub


0

Đây là mã của tôi, đây là phiên bản sửa đổi của ví dụ này

Thư viện:

class NumPermExample
{
    // print N! permutation of the characters of the string s (in order)
    public  static void perm1(String s, ArrayList<String> perm)
    {
        perm1("", s);
    }

    private static void perm1(String prefix, String s, ArrayList<String> perm)
    {
        int N = s.length();
        if (N == 0)
        {
            System.out.println(prefix);
            perm.add(prefix);
        }
        else
        {
            for (int i = 0; i < N; i++)
                perm1(prefix + s.charAt(i), s.substring(0, i)
                    + s.substring(i+1, N));
        }

    }

    // print N! permutation of the elements of array a (not in order)
    public static void perm2(String s, ArrayList<String> perm)
    {
       int N = s.length();
       char[] a = new char[N];
       for (int i = 0; i < N; i++)
           a[i] = s.charAt(i);
       perm2(a, N);
    }

    private static void perm2(char[] a, int n, ArrayList<String> perm)
    {
        if (n == 1)
        {
            System.out.println(a);
            perm.add(new String(a));
            return;
        }

        for (int i = 0; i < n; i++)
        {
            swap(a, i, n-1);
            perm2(a, n-1);
            swap(a, i, n-1);
        }
    }  

    // swap the characters at indices i and j
    private static void swap(char[] a, int i, int j)
    {
        char c;
        c = a[i]; a[i] = a[j]; a[j] = c;
    }

    // next higher permutation
    public static int nextPermutation (int number)
    {
        ArrayList<String> perm = new ArrayList<String>();

        String cur = ""+number;

        int nextPerm = 0;

        perm1(cur, perm);

        for (String s : perm)
        {
            if (Integer.parseInt(s) > number
                        && (nextPerm == 0 ||
                            Integer.parseInt(s) < nextPerm))
            {
                nextPerm = Integer.parseInt(s);
            }
        }

            return nextPerm;
    }
}

Kiểm tra:

public static void main(String[] args) 
{
    int a = 38276;

    int b = NumPermExample.nextPermutation(a);

    System.out.println("a: "+a+", b: "+b);
}

0

Thêm 9 vào số n chữ số đã cho. Sau đó kiểm tra xem nó có nằm trong giới hạn (số chữ số đầu tiên (n + 1) không). Nếu đó là kiểm tra xem các chữ số trong số mới có giống với các chữ số trong số ban đầu không. Lặp lại thêm 9 cho đến khi cả hai điều kiện là đúng. Dừng algo khi số lượng vượt quá giới hạn.

Tôi không thể đưa ra một trường hợp thử nghiệm mâu thuẫn cho phương pháp này.


1
Nó hoạt động, nhưng cực kỳ chậm. Đây là một thuật toán thời gian theo cấp số nhân, trong đó điều này có thể được giải quyết trong thời gian tuyến tính.
interjay

0

Chỉ là một giải pháp khác sử dụng python:

def PermutationStep(num):
    if sorted(list(str(num)), reverse=True) == list(str(num)):
        return -1
    ls = list(str(num))
    n = 0
    inx = 0
    for ind, i in enumerate(ls[::-1]):
        if i < n:
            n = i
            inx = -(ind + 1)
            break
        n = i
    ls[inx], ls[inx + 1] = ls[inx + 1], ls[inx]

    nl = ls[inx::-1][::-1]
    ln = sorted(ls[inx+1:])
    return ''.join(nl) + ''.join(ln)

print PermutationStep(23514)

Đầu ra:

23541

0
public static void findNext(long number){

        /* convert long to string builder */    

        StringBuilder s = new StringBuilder();
        s.append(number);
        int N = s.length();
        int index=-1,pivot=-1;

/* from tens position find the number (called pivot) less than the number in right */ 

        for(int i=N-2;i>=0;i--){

             int a = s.charAt(i)-'0';
             int b = s.charAt(i+1)-'0';

             if(a<b){
                pivot = a;
                index =i;
                break;
            }
        }

      /* if no such pivot then no solution */   

        if(pivot==-1) System.out.println(" No such number ")

        else{   

     /* find the minimum highest number to the right higher than the pivot */

            int nextHighest=Integer.MAX_VALUE, swapIndex=-1;

            for(int i=index+1;i<N;i++){

            int a = s.charAt(i)-'0';

            if(a>pivot && a<nextHighest){
                    nextHighest = a;
                    swapIndex=i;
                }
            }


     /* swap the pivot and next highest number */

            s.replace(index,index+1,""+nextHighest);
            s.replace(swapIndex,swapIndex+1,""+pivot);

/* sort everything to right of pivot and replace the sorted answer to right of pivot */

            char [] sort = s.substring(index+1).toCharArray();
            Arrays.sort(sort);

            s.replace(index+1,N,String.copyValueOf(sort));

            System.out.println("next highest number is "+s);
        }

    }

0

Dưới đây là mã để tạo ra tất cả các hoán vị của một số .. mặc dù trước tiên người ta phải chuyển đổi số nguyên đó thành chuỗi bằng String.valueOf (số nguyên).

/**
 * 
 * Inserts a integer at any index around string.
 * 
 * @param number
 * @param position
 * @param item
 * @return
 */
public String insertToNumberStringAtPosition(String number, int position,
        int item) {
    String temp = null;
    if (position >= number.length()) {
        temp = number + item;
    } else {
        temp = number.substring(0, position) + item
                + number.substring(position, number.length());
    }
    return temp;
}

/**
 * To generate permutations of a number.
 * 
 * @param number
 * @return
 */
public List<String> permuteNumber(String number) {
    List<String> permutations = new ArrayList<String>();
    if (number.length() == 1) {
        permutations.add(number);
        return permutations;
    }
    // else
    int inserterDig = (int) (number.charAt(0) - '0');
    Iterator<String> iterator = permuteNumber(number.substring(1))
            .iterator();
    while (iterator.hasNext()) {
        String subPerm = iterator.next();
        for (int dig = 0; dig <= subPerm.length(); dig++) {
            permutations.add(insertToNumberStringAtPosition(subPerm, dig,
                    inserterDig));
        }
    }
    return permutations;
}

0
#include<bits/stdc++.h>
using namespace std;
int main() 
{
    int i,j,k,min,len,diff,z,u=0,f=0,flag=0;
    char temp[100],a[100]`enter code here`,n;
    min=9999;
    //cout<<"Enter the number\n";
    cin>>a;
    len=strlen(a);
    for(i=0;i<len;i++)
    {
        if(a[i]<a[i+1]){flag=1;break;}
    }
    if(flag==0){cout<<a<<endl;}
    else
    {
        for(i=len-1;i>=0;i--)if(((int)a[i-1])<((int)a[i]))break;
        for(k=0;k<i-1;k++)cout<<a[k];
        for(j=i;j<len;j++)
        {
            if(((int)a[j]-48)-((int)a[i-1]-48)>0)
            {
                diff=((int)a[j]-48)-((int)a[i-1]-48);
                if(diff<min){n=a[j];min=diff;}
            }
        }
        cout<<n;
        for(z=i-1;z<len;z++)
        {
            temp[u]=a[z];
            u++;
        }
        temp[u]='\0';
        sort(temp,temp+strlen(temp));
        for(z=0;z<strlen(temp);z++){if(temp[z]==n&&f==0){f=1;continue;}cout<<temp[z];}
    }
    return 0;
}

0

Một triển khai Java khác, có thể chạy ra khỏi hộp và hoàn thành với các thử nghiệm. Giải pháp này là O (n) không gian và thời gian sử dụng lập trình động cũ tốt.

Nếu một người muốn bruteforce, có 2 loại bruteforce:

  1. Cho phép tất cả mọi thứ, sau đó chọn min cao hơn: O (n!)

  2. Tương tự như cách triển khai này, nhưng thay vì DP, việc xác định lại bước thực hiện bản đồ indexTo IndexOfNextSmallerLeft sẽ chạy trong O (n ^ 2).


import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class NextHigherSameDigits {

    public long next(final long num) {
        final char[] chars = String.valueOf(num).toCharArray();
        final int[] digits = new int[chars.length];
        for (int i = 0; i < chars.length; i++) {
            digits[i] = Character.getNumericValue(chars[i]);
        }

        final Map<Integer, Integer> indexToIndexOfNextSmallerLeft = new HashMap<>();
        indexToIndexOfNextSmallerLeft.put(1, digits[1] > digits[0] ? 0 : null);
        for (int i = 2; i < digits.length; i++) {
            final int left = digits[i - 1];
            final int current = digits[i];
            Integer indexOfNextSmallerLeft = null;
            if (current > left) {
                indexOfNextSmallerLeft = i - 1;
            } else {
                final Integer indexOfnextSmallerLeftOfLeft = indexToIndexOfNextSmallerLeft.get(i - 1);
                final Integer nextSmallerLeftOfLeft = indexOfnextSmallerLeftOfLeft == null ? null : 
                    digits[indexOfnextSmallerLeftOfLeft];

                if (nextSmallerLeftOfLeft != null && current > nextSmallerLeftOfLeft) {
                    indexOfNextSmallerLeft = indexOfnextSmallerLeftOfLeft;
                } else {
                    indexOfNextSmallerLeft = null;
                }
            }

            indexToIndexOfNextSmallerLeft.put(i, indexOfNextSmallerLeft);
        }

        Integer maxOfindexOfNextSmallerLeft = null;
        Integer indexOfMinToSwapWithNextSmallerLeft = null;
        for (int i = digits.length - 1; i >= 1; i--) {
            final Integer indexOfNextSmallerLeft = indexToIndexOfNextSmallerLeft.get(i);
            if (maxOfindexOfNextSmallerLeft == null ||
                    (indexOfNextSmallerLeft != null && indexOfNextSmallerLeft > maxOfindexOfNextSmallerLeft)) {

                maxOfindexOfNextSmallerLeft = indexOfNextSmallerLeft;
                if (maxOfindexOfNextSmallerLeft != null && (indexOfMinToSwapWithNextSmallerLeft == null || 
                        digits[i] < digits[indexOfMinToSwapWithNextSmallerLeft])) {

                    indexOfMinToSwapWithNextSmallerLeft = i;
                }
            }
        }

        if (maxOfindexOfNextSmallerLeft == null) {
            return -1;
        } else {
            swap(digits, indexOfMinToSwapWithNextSmallerLeft, maxOfindexOfNextSmallerLeft);
            reverseRemainingOfArray(digits, maxOfindexOfNextSmallerLeft + 1);
            return backToLong(digits);
        }
    }

    private void reverseRemainingOfArray(final int[] digits, final int startIndex) {
        final int[] tail = Arrays.copyOfRange(digits, startIndex, digits.length);
        for (int i = tail.length - 1; i >= 0; i--) {
            digits[(digits.length - 1)  - i] = tail[i];                 
        }
    }

    private void swap(final int[] digits, final int currentIndex, final int indexOfNextSmallerLeft) {
        int temp = digits[currentIndex];
        digits[currentIndex] = digits[indexOfNextSmallerLeft];
        digits[indexOfNextSmallerLeft] = temp;
    }

    private long backToLong(int[] digits) {     
        StringBuilder sb = new StringBuilder();
        for (long i : digits) {
            sb.append(String.valueOf(i));
        }

        return Long.parseLong(sb.toString());
    }

    @Test
    public void test() {
        final long input1 =    34722641;
        final long expected1 = 34724126;
        final long output1 = new NextHigherSameDigits().next(input1);
        assertEquals(expected1, output1);

        final long input2 =    38276;
        final long expected2 = 38627;
        final long output2 = new NextHigherSameDigits().next(input2);
        assertEquals(expected2, output2);

        final long input3 =    54321;
        final long expected3 = -1;
        final long output3 = new NextHigherSameDigits().next(input3);
        assertEquals(expected3, output3);

        final long input4 =    123456784987654321L;
        final long expected4 = 123456785123446789L;
        final long output4 = new NextHigherSameDigits().next(input4);
        assertEquals(expected4, output4);

        final long input5 =    9999;
        final long expected5 = -1;
        final long output5 = new NextHigherSameDigits().next(input5);
        assertEquals(expected5, output5);
    }

}

0

Chúng ta cần tìm đúng 0 bit nhất theo sau 1 và lật đúng 0 bit này sang 1.

ví dụ: giả sử đầu vào của chúng tôi là 487, là 111100111 ở dạng nhị phân.

chúng ta lật đúng 0 nhất có 1 theo sau nó

vì vậy chúng tôi nhận được 111101111

nhưng bây giờ chúng ta có thêm 1 và một ít hơn 0, vì vậy chúng ta giảm số 1 ở bên phải của bit lật xuống 1 và tăng số 0 của 0 lên 1, mang lại

111101011 - nhị phân 491

int getNextNumber(int input)
{
    int flipPosition=0;
    int trailingZeros=0;
    int trailingOnes=0;
    int copy = input;

    //count trailing zeros
    while(copy != 0 && (copy&1) == 0 )
    {
        ++trailingZeros;

        //test next bit
        copy = copy >> 1;
    }

    //count trailing ones
    while(copy != 0 && (copy&1) == 1 )
    {
        ++trailingOnes;

        //test next bit
        copy = copy >> 1;
    }

    //if we have no 1's (i.e input is 0) we cannot form another pattern with 
    //the same number of 1's which will increment the input, or if we have leading consecutive
    //ones followed by consecutive 0's up to the maximum bit size of a int
    //we cannot increase the input whilst preserving the original no of 0's and
    //1's in the bit pattern
    if(trailingZeros + trailingOnes  == 0 || trailingZeros + trailingOnes == 31)
        return -1;

    //flip first 0 followed by a 1 found from the right of the bit pattern
    flipPosition = trailingZeros + trailingOnes+1;
    input |= 1<<(trailingZeros+trailingOnes);

    //clear fields to the right of the flip position
    int mask = ~0 << (trailingZeros+trailingOnes);
    input &= mask;

    //insert a bit pattern to the right of the flip position that will contain
    //one less 1 to compensate for the bit we switched from 0 to 1
    int insert = flipPosition-1;
    input |= insert;

    return input;
}

0
int t,k,num3,num5;
scanf("%d",&t);
int num[t];
for(int i=0;i<t;i++){
    scanf("%d",&num[i]);   
}
for(int i=0;i<t;i++){
    k=(((num[i]-1)/3)+1); 
    if(k<0)
        printf("-1");
    else if(num[i]<3 || num[i]==4 || num[i]==7)
        printf("-1");
    else{
        num3=3*(2*num[i] - 5*k);
        num5=5*(3*k -num[i]);
        for(int j=0;j<num3;j++)
            printf("5");
        for(int j=0;j<num5;j++)
            printf("3");
    }
    printf("\n");
}

0

Đây là triển khai Java

public static int nextHigherNumber(int number) {
    Integer[] array = convertToArray(number);
    int pivotIndex = pivotMaxIndex(array);
    int digitInFirstSequence = pivotIndex -1;
    int lowerDigitIndexInSecondSequence = lowerDigitIndex(array[digitInFirstSequence], array, pivotIndex);
    swap(array, digitInFirstSequence, lowerDigitIndexInSecondSequence);
    doRercursiveQuickSort(array, pivotIndex, array.length - 1);
    return arrayToInteger(array);
}

public static Integer[] convertToArray(int number) {
    int i = 0;
    int length = (int) Math.log10(number);
    int divisor = (int) Math.pow(10, length);
    Integer temp[] = new Integer[length + 1];

    while (number != 0) {
        temp[i] = number / divisor;
        if (i < length) {
            ++i;
        }
        number = number % divisor;
        if (i != 0) {
            divisor = divisor / 10;
        }
    }
    return temp;
}

private static int pivotMaxIndex(Integer[] array) {
    int index = array.length - 1;
    while(index > 0) {
        if (array[index-1] < array[index]) {
            break;
        }
        index--;
    }       
    return index;
}

private static int lowerDigitIndex(int number, Integer[] array, int fromIndex) {
    int lowerMaxIndex = fromIndex;
    int lowerMax = array[lowerMaxIndex];
    while (fromIndex < array.length - 1) {
        if (array[fromIndex]> number && lowerMax > array[fromIndex]) {
            lowerMaxIndex = fromIndex; 
        }
        fromIndex ++;
    }
    return lowerMaxIndex;
}

public static int arrayToInteger(Integer[] array) {
    int number = 0;
    for (int i = 0; i < array.length; i++) {
        number+=array[i] * Math.pow(10, array.length-1-i);
    }
    return number;
}

Đây là bài kiểm tra đơn vị

@Test
public void nextHigherNumberTest() {
    assertThat(ArrayUtils.nextHigherNumber(34722641), is(34724126));
    assertThat(ArrayUtils.nextHigherNumber(123), is(132));
}

0

Tôi biết đây là câu hỏi rất cũ nhưng tôi vẫn không tìm thấy mã dễ dàng trong c #. Điều này có thể giúp những người đang tham dự các cuộc phỏng vấn.

class Program
{
    static void Main(string[] args)
    {

        int inputNumber = 629;
        int i, currentIndexOfNewArray = 0;

        int[] arrayOfInput = GetIntArray(inputNumber);
        var numList = arrayOfInput.ToList();

        int[] newArray = new int[arrayOfInput.Length];

        do
        {
            int temp = 0;
            int digitFoundAt = 0;
            for (i = numList.Count; i > 0; i--)
            {
                if (numList[i - 1] > temp)
                {
                    temp = numList[i - 1];
                    digitFoundAt = i - 1;
                }
            }

            newArray[currentIndexOfNewArray] = temp;
            currentIndexOfNewArray++;
            numList.RemoveAt(digitFoundAt);
        } while (arrayOfInput.Length > currentIndexOfNewArray);



        Console.WriteLine(GetWholeNumber(newArray));

        Console.ReadKey();


    }

    public static int[] GetIntArray(int num)
    {
        IList<int> listOfInts = new List<int>();
        while (num > 0)
        {
            listOfInts.Add(num % 10);
            num = num / 10;
        }
        listOfInts.Reverse();
        return listOfInts.ToArray();
    }

    public static double GetWholeNumber(int[] arrayNumber)
    {
        double result = 0;
        double multiplier = 0;
        var length = arrayNumber.Count() - 1;
        for(int i = 0; i < arrayNumber.Count(); i++)
        {
            multiplier = Math.Pow(10.0, Convert.ToDouble(length));
            result += (arrayNumber[i] * multiplier);
            length = length - 1;
        }

        return result;
    }
}

0

Thực hiện rất đơn giản bằng Javascript, số cao nhất tiếp theo có cùng chữ số

/*
Algorithm applied
I) Traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit. For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. If we do not find such a digit, then output is “Not Possible”.

II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6.

III) Swap the above found two digits, we get 536974 in above example.

IV) Now sort all digits from position next to ‘d’ to the end of number. The number that we get after sorting is the output. For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976.

*/

function findNext(arr)
{
  let i;
  //breaking down a digit into arrays of string and then converting back that array to number array
  let arr1=arr.toString().split('').map(Number) ;
  //started to loop from the end of array 
  for(i=arr1.length;i>0;i--)
  {
    //looking for if the current number is greater than the number next to it
    if(arr1[i]>arr1[i-1])
    {// if yes then we break the loop it so that we can swap and sort
      break;}
  }

  if(i==0)
  {console.log("Not possible");}

   else
  {
   //saving that big number and smaller number to the left of it
   let smlNum =arr1[i-1];
    let bigNum =i;
   /*now looping again and checking if we have any other greater number, if we have one AFTER big number and smaller number to the right. 
     A greater number that is of course greater than that smaller number but smaller than the first number we found.
     Why are doing this? Because that is an algorithm to find next higher number with same digits. 
   */
    for(let j=i+1;j<arr1.length;j++)
      {//What if there are no digits afters those found numbers then of course loop will not be initiated otherwise...
        if(arr1[j]> smlNum && arr1[j]<arr1[i])
        {// we assign that other found number here and replace it with the one we found before
          bigNum=j;

        }
      } //now we are doing swapping of places the small num and big number , 3rd part of alogorithm
    arr1[i-1]=arr1[bigNum];
          arr1[bigNum]=smlNum;
    //returning array 
    //too many functions applied sounds complicated right but no, here is the  trick
    //return arr first then apply each function one by one to see output and then further another func to that output to match your needs
    // so here after swapping , 4th part of alogorithm is to sort the array right after the 1st small num we found
    // to do that first we simple take part of array, we splice it and then we apply sort fucntion, then check output (to check outputs, pls use chrome dev console)
    //and then  simply the rest concat and join to main one digit again.
     return arr1.concat((arr1.splice(i,arr1.length)).sort(function(a, b){return a-b})).join('');



    // Sorry to make it too long but its fun explaining things in much easier ways as much as possible!!
  }

}


findNext(1234);

Vì có rất nhiều bình luận, vì vậy tốt hơn là bạn có thể sao chép nó vào trình soạn thảo văn bản của mình. Cảm ơn!


0

Có rất nhiều câu trả lời hay nhưng tôi đã không tìm thấy một triển khai Java tốt. Đây là hai xu của tôi:

public void findNext(int[] nums) {
    int i = nums.length - 1;
    // nums[i - 1] will be the first non increasing number
    while (i > 0 && nums[i] <= nums[i - 1]) {
        i--;
    }
    if (i == 0) {
        System.out.println("it has been the greatest already");
    } else {
        // Find the smallest digit in the second sequence that is larger than it:
        int j = nums.length - 1;
        while (j >= 0 && nums[j] < nums[i - 1]) {
            j--;
        }
        swap(nums, i - 1, j);
        Arrays.sort(nums, i, nums.length);
        System.out.println(Arrays.toString(nums));
    }
}

public void swap(int[] nums, int i, int j) {
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}

0
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<string.h>
#include<sstream>
#include<iostream>

using namespace std;
int compare (const void * a, const void * b)
{
    return *(char*)a-*(char*)b;
}

/*-----------------------------------------------*/

int main()
{
    char number[200],temp;
    cout<<"please enter your number?"<<endl;
    gets(number);
    int n=strlen(number),length;
    length=n;
    while(--n>0)
    {
        if(number[n-1]<number[n])
        {
            for(int i=length-1;i>=n;i--)
            {
                if(number[i]>number[n-1])
                {
                    temp=number[i];
                    number[i]=number[n-1];
                    number[n-1]=temp;
                    break;
                }
            }
            qsort(number+n,length-n,sizeof(char),compare);
            puts(number); 
            return 0;
        }
    }
    cout<<"sorry itz the greatest one :)"<<endl;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.