กำหนดตัวเลขให้ค้นหาตัวเลขที่สูงกว่าถัดไปซึ่งมีชุดตัวเลขที่แน่นอนเหมือนกับหมายเลขเดิม


226

ฉันเพิ่งวางระเบิดการสัมภาษณ์และทำให้ความคืบหน้าของคำถามสัมภาษณ์ค่อนข้างเป็นศูนย์ ใครช่วยให้ฉันรู้วิธีการทำเช่นนี้? ฉันพยายามค้นหาออนไลน์ แต่ไม่พบอะไรเลย:

กำหนดตัวเลขให้ค้นหาตัวเลขที่สูงกว่าถัดไปซึ่งมีชุดตัวเลขที่แน่นอนเหมือนกับหมายเลขเดิม ตัวอย่างเช่น: รับ 38276 ส่งคืน 38627

ฉันต้องการเริ่มต้นด้วยการค้นหาดัชนีของตัวเลขแรก (จากด้านขวา) ที่น้อยกว่าตัวเลขหลัก จากนั้นฉันจะหมุนตัวเลขสุดท้ายในชุดย่อยเพื่อให้เป็นตัวเลขที่ใหญ่ที่สุดถัดไปซึ่งประกอบด้วยตัวเลขเดียวกัน แต่ติดอยู่

ผู้สัมภาษณ์ยังแนะนำให้พยายามเปลี่ยนตัวเลขทีละหนึ่ง แต่ฉันไม่สามารถหาอัลกอริทึมและจ้องมองที่หน้าจอเป็นเวลา 20-30 นาที ฉันคิดว่าฉันคงต้องออกไปหางานทำต่อไป

แก้ไข: สำหรับสิ่งที่คุ้มค่าฉันได้รับเชิญให้สัมภาษณ์รอบต่อไป


15
โดยไม่ต้องคิดอะไรมากการเริ่มต้นอย่างน้อยที่สุดก็คือแรงเดรัจฉานบังคับคำนวณการเรียงสับเปลี่ยนของตัวเลขทั้งหมดและคว้าจำนวนขั้นต่ำที่มากกว่าจำนวนอินพุต
BrokenGlass

13
ใน C ++ คุณสามารถใช้next_permutation;-)
thedayturns

9
FYI นี่คือวิธีที่ฉันแก้ไขได้ในเวลาประมาณ 15 นาทีในขณะที่เพิ่งจะคิดถึงปัญหา: ฉันใช้เวลา 5 นาทีในการเขียนอัลกอริธึมกำลังดุร้ายที่เพิ่งสร้างการเรียงสับเปลี่ยนที่เป็นไปได้ทั้งหมดของชุดตัวเลขเรียงลำดับและแสดงมัน ผมใช้เวลา 5 นาทีการมองผ่านว่าข้อมูลจนกระทั่งรูปแบบที่โผล่ออกมาจากรายการนี้ (O (n) การแก้ปัญหาได้รับการยอมรับที่นี่กลายเป็นที่ชัดเจนหลังจากนั้นเพียงช่วงเวลาสั้น ๆ มอง) แล้วผมใช้เวลา 5 นาทีเข้ารหัส O (n) อัลกอริทึม
เบ็นลี

1
โดยทั่วไปนี่ไม่ใช่วิธีที่ไม่ดีในการหาอัลกอริธึมในการแก้ปัญหาแบบนี้เมื่อคุณติดอยู่ใช้แรงเดรัจฉานกับตัวอย่างเล็ก ๆ เพื่อสร้างข้อมูลจำนวนมากซึ่งคุณสามารถใช้เพื่อดูรูปแบบได้ง่ายขึ้น
เบ็นลี

19
ที่ฉันยังต้องการจะชี้ให้เห็นว่าถ้าคุณจริงๆไม่สามารถคิดออกวิธีที่มีประสิทธิภาพในการทำเช่นนี้ทำอะไรเป็นวิธีการตรวจสอบที่จะล้มเหลวการสัมภาษณ์ (และในโลกธุรกิจก็เป็นวิธีการตรวจสอบที่จะพลาดเส้นตายผลิตภัณฑ์) . เมื่อคุณติดแทนที่จะยอมแพ้คุณควรจะดุร้ายและใส่ความเห็นไว้ด้านบน "TODO: refactor for performance" หรืออะไรทำนองนั้น ถ้าฉันสัมภาษณ์และมีคนทำเช่นนั้นฉันก็ไม่จำเป็นต้องทำผิดพลาด อย่างน้อยพวกเขาก็คิดหาสิ่งที่ใช้งานได้และจำได้ว่ามีบางอย่างที่ดีกว่าอยู่ที่นั่นแม้ว่าพวกเขาจะหาไม่พบก็ตาม
Ben Lee

คำตอบ:


272

คุณสามารถทำได้ในO(n)(ซึ่งnเป็นจำนวนหลัก) เช่นนี้:

เริ่มต้นจากด้านขวาคุณจะพบคู่หลักของตัวเลขแรกที่หลักซ้ายมีขนาดเล็กกว่าหลักขวา ลองอ้างอิงตัวเลขทางซ้ายด้วย "digit-x" ค้นหาตัวเลขที่เล็กที่สุดที่มากกว่าดิจิตัล x ​​ทางด้านขวาของดิจิต -x แล้ววางไว้ที่ดิจิตัล x ในที่สุดการจัดเรียงตัวเลขที่เหลือในการเรียงลำดับ - ตั้งแต่ที่พวกเขามีอยู่แล้วในลงมาเพื่อสิ่งที่คุณต้องทำคือการย้อนกลับพวกเขา(ยกเว้นหลัก x ซึ่งสามารถอยู่ในตำแหน่งที่ถูกต้องในO(n) )

ตัวอย่างจะทำให้ชัดเจนยิ่งขึ้น:

123456784987654321
เริ่มต้นด้วยตัวเลข

123456784 987654321
         ^ ตำแหน่งแรกจากด้านขวาซึ่งตัวเลขทางซ้ายน้อยกว่าทางขวา  
         ตัวเลข "x" คือ 4

123456784 987654321
              ^ ค้นหาตัวเลขที่เล็กที่สุดที่มากกว่า 4 ทางด้านขวา

123456785 4 98764321
        ^ วางไปทางซ้ายของ 4

123456785 4 12346789
123456785123446789
         ^ เรียงลำดับตัวเลขทางด้านขวาของ 5 เนื่องจากทั้งหมดยกเว้น 
         '4' นั้นเรียงลำดับจากมากไปน้อยสิ่งที่เราต้องทำคือ 
         กลับคำสั่งซื้อของพวกเขาและค้นหาสถานที่ที่ถูกต้องสำหรับ '4'

หลักฐานความถูกต้อง:

ลองใช้ตัวอักษรพิมพ์ใหญ่เพื่อกำหนดตัวเลขและตัวพิมพ์เล็กสำหรับตัวเลข ไวยากรณ์ABหมายถึง"การเรียงต่อกันของสตริงAและB " <คือการเรียงลำดับพจนานุกรมโดยย่อซึ่งจะเหมือนกับการเรียงจำนวนเต็มเมื่อสตริงหลักมีความยาวเท่ากัน

หมายเลข N ดั้งเดิมของเราอยู่ในรูปแบบAxBที่xเป็นตัวเลขหลักเดียวและBเรียงจากมากไปน้อย
จำนวนที่พบโดยอัลกอริทึมของเราคือAyCซึ่งy ∈ Bเป็นตัวเลขที่เล็กที่สุด> x (ต้องมีอยู่เนื่องจากวิธีที่xถูกเลือกดูด้านบน)และCเรียงจากน้อยไปมาก

ถือว่ามีจำนวนบางคน (โดยใช้หลักเดียวกัน) ดังกล่าวว่า N' ต้องเริ่มต้นด้วยหรืออื่น ๆ มันไม่สามารถตกอยู่ระหว่างพวกเขาเพื่อให้เราสามารถเขียนในรูปแบบ ตอนนี้ความไม่เท่าเทียมของเราคือซึ่งเทียบเท่ากับที่ทั้งสามสายหลักมีตัวเลขเดียวกันAxB < N' < AyCN'AAzDAxB < AzD < AyCxB < zD < yC

x <= z <= yเพื่อที่จะเป็นจริงเราจะต้องมี ตั้งแต่yเป็นหลักมีขนาดเล็กที่สุด> x, zไม่สามารถระหว่างพวกเขาดังนั้นทั้งหรือz = x พูดz = y z = xจากนั้นความไม่เท่าเทียมของเราคือxB < xD < yCซึ่งหมายความว่าB < Dทั้งสองBและDมีตัวเลขเดียวกัน อย่างไรก็ตาม B คือจากมากไปน้อยเรียงจึงมีเป็นสตริงด้วยตัวเลขที่มีขนาดใหญ่เกินกว่าที่จะไม่มี B < Dดังนั้นเราจึงไม่สามารถมี ทำตามขั้นตอนเดียวกันเราเห็นว่าถ้าเราไม่สามารถมีz = yD < C

ดังนั้นจึงN'ไม่มีอยู่ซึ่งหมายความว่าอัลกอริทึมของเราจะค้นหาหมายเลขที่ใหญ่ที่สุดถัดไปได้อย่างถูกต้อง


7
ทางออกที่ดี! มีคำถามหนึ่งข้อ พูดว่า "ตัวเลขที่เล็กที่สุดที่ใหญ่กว่า x" คือ y เราสามารถสลับ x และ y แล้วย้อนกลับ x.index + 1 -> สิ้นสุดได้ไหม
Kent

8
เกิดอะไรขึ้นกับหมายเลข 99999
Sterex

19
@Serex ไม่ใช่แค่ 99999 เท่านั้น หมายเลขใด ๆ ที่มีตัวเลขเรียงลำดับจากมากไปหาน้อยคือสูงสุด (ดังนั้น 98765 ก็ไม่มีวิธีแก้ปัญหาเช่น) สิ่งนี้ง่ายต่อการตรวจสอบโดยทางโปรแกรมเนื่องจากขั้นตอนที่ 1 ของอัลกอริธึมจะล้มเหลว (ไม่มีตัวเลขคู่ติดต่อกันเช่น "ตัวเลขทางซ้ายมีขนาดเล็กกว่าหลักขวา")
เบ็นลี

3
@TMN: 9 มีขนาดใหญ่กว่า 8 ดังนั้นคุณจะย้าย 9 ไปทางซ้าย 8: 9 832เรียงลำดับทุกอย่างไปทางขวาของ 9:9238
BlueRaja - Danny Pflughoeft

4
@ Kent สำหรับการแก้ปัญหาของคุณในการทำงานของคุณจะมีการเปลี่ยนแปลงพบว่าหลักที่เล็กที่สุดมีขนาดใหญ่กว่า 4 เพื่อสิทธิในการที่จะหาสิ่งที่หลักที่เล็กที่สุดมีขนาดใหญ่กว่า 4 จากด้านขวา มิฉะนั้นเช่น 1234567849876 55 4321 จะส่งผลให้ 1234567851234 54 6789 (แทน 1234567851234 45 6789) A nitpick :-)
osundblad

94

ปัญหาที่เกือบเหมือนกันปรากฏเป็นปัญหา Code Jam และมีวิธีแก้ไข:

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

นี่เป็นบทสรุปของวิธีการโดยใช้ตัวอย่าง:

34722641

A. แบ่งลำดับของตัวเลขสองหลักเพื่อให้ส่วนที่ถูกต้องยาวที่สุดเท่าที่จะเป็นไปได้ในขณะที่ยังคงอยู่ในลำดับที่ลดลง:

34722 641

(หากจำนวนทั้งหมดอยู่ในลำดับที่ลดลงจะไม่มีการทำตัวเลขที่ใหญ่กว่านี้โดยไม่เพิ่มตัวเลข)

B.1 เลือกตัวเลขสุดท้ายของลำดับแรก:

3472(2) 641

B.2 ค้นหาตัวเลขที่เล็กที่สุดในลำดับที่สองที่ใหญ่กว่า:

3472(2) 6(4)1

B.3 สลับพวกเขา:

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

C. เรียงลำดับที่สองเป็นลำดับที่เพิ่มขึ้น:

34724 126

เสร็จแล้ว!

34724126

1
พิมพ์ที่นั่น: ฉันคิดว่า "-> 34721 621" ควรเป็น "-> 34724 621"?
bjnord

1
@bjnord จับได้ดี แก้ไขแล้ว. ไม่แน่ใจว่าฉันจัดการได้อย่างไร - มันถูกต้องในบรรทัดต่อมา
Weeble

+1 คำตอบที่ดีที่สุดที่นี่ ใช้งานง่ายและรวดเร็ว (ยังเป็นคนที่ฉันคิดว่าเมื่อฉันทำสิ่งนี้บนกระดาษ;)
Muhd

1
@Neel - ในขั้นตอน C ตัวเลขที่เราต้องการเรียงตามลำดับจากมากไปน้อยยกเว้นตัวเลขที่เราสลับในขั้นตอน B เพื่อจัดเรียงพวกเราจริง ๆ แล้วเราเพียงแค่ต้องการย้อนกลับและรับตัวเลขที่เปลี่ยนในตำแหน่งที่ถูกต้อง นี่คือสิ่งที่ BlueRaja อธิบาย
Weeble

1
@ Dhavaldave มีปัญหาอะไร? ในขั้นตอน A คุณจะได้รับ "12" และ "3" ในขั้นตอน B คุณจะได้รับ "13" และ "2" ในขั้นตอน C ไม่มีอะไรเปลี่ยนแปลง ในขั้นตอน D คุณจะได้รับ "132" กรณีเดียวที่คุณจะไม่ได้รับคำตอบคือเมื่อมีจำนวนมากที่สุดเท่าที่เป็นไปได้เช่น "321" ในกรณีนั้นขั้นตอน A จะให้ "" และ "321" และคุณไม่สามารถดำเนินการตามลำดับที่ว่างสำหรับด้านซ้ายของการแยก
Weeble

14

นี่คือโซลูชันขนาดกะทัดรัด (แต่กำลังดุร้ายบางส่วน) ใน Python

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

ใน C ++ คุณสามารถทำการเรียงสับเปลี่ยนดังนี้: https://stackoverflow.com/a/9243091/1149664 (เป็นอัลกอริทึมเดียวกับที่อยู่ใน itertools)

นี่คือการใช้คำตอบยอดนิยมที่อธิบายโดย Weeble และ BlueRaja (คำตอบอื่น ๆ ) ฉันสงสัยว่ามีอะไรดีกว่านี้

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)))))

โอกาสใด ๆ ที่ทุกคนสามารถอัปเดตได้โปรด? ดูเหมือนจะไม่ทำงานในหลาม 3 type 'map' has no len()ในขณะที่มันแสดงให้เห็นว่า iis=list(map(int,str(ii)))ฉันต้องการเพียงแค่เปลี่ยนบรรทัดที่ 2 และทุกคนสามารถอธิบายif i == 0: return iiบรรทัดได้ไหม ทำไมมันถึงใช้ได้กับอินพุทเช่น 111 หรือ 531 ขอบคุณ
Bowen Liu

ฉันแก้ไข python 3 แล้วโดยเพิ่ม´list () ไปยัง iis = ... ´ เคส 111 และ 531 ไม่มีวิธีแก้ปัญหา แต่การใช้งานของฉันคืนค่า 111 และ 531 สำหรับกรณีเหล่านั้น คุณสามารถเปลี่ยนสิ่งนั้นให้เป็นข้อยกเว้นของสิ่งที่คุณค้นหาได้ดีขึ้นด้วยการเปลี่ยน i == 0 บรรทัด
Johan Lundberg

ขอบคุณ ที่จริงผมห่วงในทิศทางอื่น ๆ ดังนั้นฉันถูกสับสนโดยที่ฉัน == 0 i == len(iis)ในขณะที่สถานการณ์ของฉันมันจะเป็น
Bowen Liu

8

อย่างน้อยต่อไปนี้เป็นตัวอย่างของการใช้กำลังตามวิธีการที่ดุร้ายของ String ซึ่งคุณควรจะสามารถรู้ได้จากส่วนบนของหัว:

รายการของตัวเลขในการ38276เรียงลำดับคือ23678

รายการของตัวเลขในการ38627เรียงลำดับคือ23678

การเพิ่มกำลังดุร้ายกำลังการเรียงลำดับและการเปรียบเทียบ

ตามวิธีแก้ปัญหากำลังดุร้ายจะถูกแปลงเป็นสตริงและบังคับให้ตัวเลขที่เป็นไปได้ทั้งหมดโดยใช้ตัวเลขเหล่านั้น

สร้าง ints จากพวกเขาทั้งหมดวางไว้ในรายการและเรียงลำดับรับรายการถัดไปหลังจากรายการเป้าหมาย

หากคุณใช้เวลา 30 นาทีกับสิ่งนี้และอย่างน้อยก็ไม่ได้เกิดขึ้นกับวิธีการบังคับเดรัจฉานอย่างน้อยฉันก็จะไม่จ้างคุณเช่นกัน

ในโลกธุรกิจที่แก้ปัญหาที่ไม่งดงามช้าและ clunky แต่ได้รับงานทำอยู่เสมอที่มีคุณค่ามากกว่าการแก้ปัญหาที่ทุกคนไม่เรื่องของความเป็นจริงที่อธิบายสวยมากทุกธุรกิจซอฟต์แวร์ไม่งดงามช้าและ clunky


1
ความคิดเห็นแรกของฉันเกี่ยวกับค้างคาวคือ "ฉันสามารถดุร้ายได้ แต่ ... " หากไม่มีวิธีการแก้ปัญหาแบบอัลกอริทึมจริงๆฉันก็รู้สึกผิดหวัง
2012

4
หากฉันเป็นผู้สัมภาษณ์ฉันจะไม่มีความสุขมากกับวิธีการใช้กำลังดุร้าย
Ahmad Y. Saleh

@benjamin han, มีวิธีแก้อัลกอริทึม เพียงแค่ทำการปัดตัวเลขจากขวาไปเรื่อย ๆ จนกว่าคุณจะพบผลลัพธ์ ไม่จำเป็นต้องคำนวณพีชคณิตทั้งหมดก่อน
dantuch

7
มีวิธีแก้ปัญหาที่ดีกว่าแรงเดรัจฉานเช่นardendertat.com/2012/01/01/2/…
BrokenGlass

@BrokenGlass แน่นอนทางออกที่ดีกว่ามาก ฉันเพิ่งจะเกิดขึ้นกับความคิดนั้นแล้วคุณโพสต์อัลกอริทึม
onit

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

ฉันคิดวิธีแก้ปัญหานี้ กรุณาถ้าคุณมีคำถามใด ๆ ถาม
Ashikodi

4

ความคิดของคุณ

ฉันต้องการเริ่มต้นด้วยการค้นหาดัชนีของตัวเลขแรก (จากด้านขวา) ที่น้อยกว่าตัวเลขหลัก จากนั้นฉันจะหมุนตัวเลขสุดท้ายในชุดย่อยเพื่อให้เป็นตัวเลขที่ใหญ่ที่สุดถัดไปซึ่งประกอบด้วยตัวเลขเดียวกัน แต่ติดอยู่

ค่อนข้างดีจริงๆ คุณต้องพิจารณาไม่เพียง แต่ตัวเลขสุดท้าย แต่เป็นตัวเลขที่สำคัญน้อยกว่าตัวเลขที่พิจารณาในปัจจุบัน ตั้งแต่ก่อนที่จะถึงเราจะมีลำดับของตัวเลขแบบ monotonic นั่นคือตัวเลขทางขวาสุดที่เล็กกว่าของเพื่อนบ้านที่ถูกต้อง คำนึงถึง

1234675
    ^

ตัวเลขที่ใหญ่กว่าถัดไปซึ่งมีตัวเลขเหมือนกันคือ

1234756

ตัวเลขที่พบมีการแลกเปลี่ยนสำหรับตัวเลขสุดท้าย - ที่เล็กที่สุดของตัวเลขที่พิจารณา - และตัวเลขที่เหลือจะถูกจัดเรียงในลำดับที่เพิ่มขึ้น


4

ฉันค่อนข้างแน่ใจว่าผู้สัมภาษณ์ของคุณพยายามผลักคุณเข้าหาสิ่งนี้:

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);

ไม่จำเป็นต้องเป็นโซลูชั่นที่มีประสิทธิภาพหรือสวยงามที่สุด แต่มันสามารถแก้ไขตัวอย่างที่ให้ไว้ในสองรอบและสลับตัวเลขหนึ่งหลักในเวลาเดียวกับที่เขาแนะนำ


2

นำตัวเลขและแยกเป็นตัวเลข ดังนั้นถ้าเรามีตัวเลข 5 หลักเราก็มี 5 หลัก: abcde

ตอนนี้สลับ d และ e และเปรียบเทียบกับหมายเลขเดิมถ้ามีขนาดใหญ่กว่าคุณมีคำตอบของคุณ

หากไม่ใหญ่กว่าให้สลับ e และ c ตอนนี้เปรียบเทียบและถ้ามันมีขนาดเล็กสลับ d และ e อีกครั้ง (สังเกตการเรียกซ้ำ) ให้ใช้เวลาน้อยที่สุด

ดำเนินการต่อไปจนกว่าคุณจะพบจำนวนที่มากขึ้น ด้วยการเรียกซ้ำมันควรจะทำงานออกเป็นประมาณ 9 บรรทัดของโครงการหรือ 20 จาก c #


2

นั่นเป็นคำถามที่น่าสนใจมาก

นี่คือเวอร์ชัน Java ของฉัน ใช้เวลาประมาณ 3 ชั่วโมงในการหารูปแบบเพื่อเสร็จสิ้นโค้ดให้สมบูรณ์ก่อนที่ฉันจะตรวจสอบความคิดเห็นของผู้มีส่วนร่วมคนอื่น ดีใจที่ได้เห็นความคิดของฉันค่อนข้างเหมือนกันกับคนอื่น ๆ

โซลูชัน O (n) สุจริตฉันจะล้มเหลวในการสัมภาษณ์ครั้งนี้หากเวลาเพียง 15 นาทีและต้องใช้รหัสเสร็จบนกระดานไวท์บอร์ด

นี่คือบางจุดที่น่าสนใจสำหรับการแก้ปัญหาของฉัน:

  • หลีกเลี่ยงการเรียงลำดับใด ๆ
  • หลีกเลี่ยงการดำเนินการกับสตริงอย่างสมบูรณ์
  • บรรลุความซับซ้อนของพื้นที่ O (logN)

ฉันใส่ความคิดเห็นอย่างละเอียดในรหัสของฉันและ Big O ในแต่ละขั้นตอน

  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;

}

นี่คือผลลัพธ์ที่ทำงานใน Intellj:

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

ในกรณีที่ 123 จะมีคำตอบอะไร? จวนจะโค้ดไม่สร้างผลในขณะที่มันมา 132
Dhaval dave

2

การใช้งานจาวาสคริปต์ของอัลกอริทึมของ @ 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

วิธีแก้ปัญหา (ใน Java) อาจเป็นดังต่อไปนี้ (ฉันแน่ใจว่าเพื่อน ๆ ที่นี่สามารถหาที่ดีกว่า):
เริ่มต้นการแลกเปลี่ยนตัวเลขจากจุดสิ้นสุดของสตริงจนกว่าคุณจะได้รับตัวเลขที่สูงขึ้น
นั่นคือเริ่มต้นที่จะเลื่อนตัวเลขหลักที่ต่ำกว่าจากนั้นเป็นต้นไปที่สูงขึ้นถัดไปจนกว่าคุณจะตีที่สูงขึ้นถัดไป
จากนั้นเรียงลำดับส่วนที่เหลือ ในตัวอย่างของคุณคุณจะได้รับ:

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: เอาท์พุทคือ63872อะไรทำไมมันควรเป็นอย่างไร
Cratylus

ดี .. หมายเลขที่สูงขึ้นต่อไป? :) นั่นเป็นข้อกำหนดใช่มั้ย
Karoly Horvath

@BlueRaja - Danny Pflughoeft: ขอบคุณสำหรับความช่วยเหลือของคุณฉันเปลี่ยนรหัสดังนี้: ย้ายตัวเลขหลักที่น้อยที่สุด (ซึ่งเคยให้จำนวนที่สูงกว่า) และเรียงลำดับที่เหลือ
Cratylus

1

หากคุณกำลังเขียนโปรแกรมใน C ++ คุณสามารถใช้ 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;
}

จะเกิดอะไรขึ้นถ้าฉันป้อนข้อมูล100? :-)
jweyrich

1

ฉันไม่รู้อะไรเกี่ยวกับอัลกอริทึมกำลังดุร้ายเมื่อตอบคำถามนี้ดังนั้นฉันจึงเข้าหามันจากอีกมุมหนึ่ง ฉันตัดสินใจที่จะค้นหาวิธีแก้ปัญหาที่เป็นไปได้ทั้งหมดซึ่งหมายเลขนี้สามารถจัดเรียงใหม่ได้โดยเริ่มจาก number_given + 1 จนถึงจำนวนสูงสุดที่มีอยู่ (999 สำหรับตัวเลข 3 หลัก, 9999 สำหรับ 4 หลักเป็นต้น) ฉันทำเช่นเดียวกับการหาคำศัพท์ด้วยการเรียงลำดับตัวเลขของการแก้ปัญหาแต่ละรายการและเปรียบเทียบกับจำนวนที่เรียงลำดับที่กำหนดเป็นพารามิเตอร์ จากนั้นฉันก็คืนค่าโซลูชันแรกในอาร์เรย์ของโซลูชันเนื่องจากนี่จะเป็นค่าถัดไปที่เป็นไปได้

นี่คือรหัสของฉันใน 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

ความซับซ้อนของเวลาในการแก้ปัญหานี้คืออะไร?
Nitish Upreti

@ Myth17 ฉันไม่แน่ใจเพราะฉันไม่เคยทดสอบ หากคุณต้องการคิดออกลองดูที่โพสต์นี้: stackoverflow.com/questions/9958299//
Jeremiah McCurdy

1

รหัส 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

ฉันแค่ทดสอบสิ่งนี้ด้วยตัวเลขสองตัว พวกเขาทำงาน ในฐานะผู้จัดการฝ่าย IT เป็นเวลา 8 ปีจนกระทั่งสิ้นสุดเดือนธันวาคมที่ผ่านมาฉันใส่ใจสามสิ่ง: 1) ความถูกต้อง: มันดีถ้ามันใช้งานได้ - เสมอ 2) ความเร็ว: ต้องยอมรับได้โดยผู้ใช้ 3) ความชัดเจน: ฉันอาจไม่ฉลาดเท่าที่คุณเป็น แต่ฉันจ่ายเงินให้คุณ ให้แน่ใจว่าคุณอธิบายสิ่งที่คุณทำในภาษาอังกฤษ

Omar โชคดีที่สุดก้าวไปข้างหน้า

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

นี่คือรหัสของฉันมันเป็นเวอร์ชันที่แก้ไขแล้วของ ตัวอย่างนี้

ห้องสมุด:

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;
    }
}

ทดสอบ:

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

    int b = NumPermExample.nextPermutation(a);

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

0

เพิ่ม 9 จำนวน n หลักที่กำหนด จากนั้นตรวจสอบว่ามันอยู่ภายในขีด จำกัด (หมายเลขแรก (n + 1) หลักหรือไม่ หากเป็นเช่นนั้นให้ตรวจสอบว่าตัวเลขในหมายเลขใหม่เป็นตัวเลขเดียวกันกับตัวเลขในหมายเลขเดิมหรือไม่ ทำซ้ำการเพิ่ม 9 จนกว่าเงื่อนไขทั้งสองจะเป็นจริง หยุดสัญลักษณ์เมื่อตัวเลขเกินขีด จำกัด

ฉันไม่สามารถคิดกรณีทดสอบที่ขัดแย้งกับวิธีนี้ได้


1
มันใช้งานได้ แต่ช้ามาก มันเป็นอัลกอริธึมเวลาเอ็กซ์โปเนนเชียลที่สามารถแก้ไขได้ในเวลาเชิงเส้น
ระหว่าง

0

อีกวิธีใช้ 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)

เอาท์พุท:

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

ด้านล่างเป็นรหัสสำหรับสร้างการเรียงสับเปลี่ยนของตัวเลข .. แม้ว่าจะต้องแปลงจำนวนเต็มนั้นเป็นสตริงโดยใช้ String.valueOf (จำนวนเต็ม) ก่อน

/**
 * 
 * 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

อีกหนึ่งการใช้งานจาวาเรียกใช้งานได้ทันทีและเสร็จสิ้นการทดสอบ วิธีนี้เป็นพื้นที่ (O) และเวลาโดยใช้การเขียนโปรแกรมแบบไดนามิกที่ดีเก่า

หากใครต้องการ bruteforce มี bruteforce 2 ชนิด:

  1. ดัดทุกสิ่งแล้วเลือก min high: O (n!)

  2. คล้ายกับการนำไปใช้งานนี้ แต่แทนที่จะเป็น DP แทนที่ขั้นตอนการเติมข้อมูลแผนที่ indexToIndexOfNextSmallerLeft จะทำงานใน 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

เราต้องหาบิตที่ถูกที่สุด 0 แล้วตามด้วย 1 และพลิกขวานี้มากที่สุด 0 บิตเป็น 1

ตัวอย่างเช่นสมมติว่าอินพุตของเราคือ 487 ซึ่งคือ 111100111 ในไบนารี

เรากลับด้านขวาที่สุด 0 ที่มี 1 ติดตาม

ดังนั้นเราจึงได้ 111101111

แต่ตอนนี้เรามี 1 พิเศษและหนึ่งน้อย 0 ดังนั้นเราจึงลดจำนวนของ 1 ทางด้านขวาของ flip bit 1 และเพิ่ม no ของ 0 bits ต่อ 1 ให้ผล

111101011 - ไบนารี 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

นี่คือการนำ 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;
}

นี่คือการทดสอบหน่วย

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

0

ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่ก็ยังไม่พบรหัสง่าย ๆ ใน c # นี่อาจช่วยคนที่เข้าร่วมการสัมภาษณ์

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

ใช้งานง่ายมากโดยใช้ Javascript เป็นจำนวนสูงสุดถัดไปด้วยตัวเลขเดียวกัน

/*
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);

เนื่องจากมีความคิดเห็นจำนวนมากดังนั้นจึงเป็นการดีกว่าที่คุณจะคัดลอกไปยังโปรแกรมแก้ไขข้อความ ขอบคุณ!


0

มีคำตอบที่ดีมากมาย แต่ฉันไม่พบการนำ Java ไปใช้อย่างเหมาะสม นี่คือสองเซ็นต์ของฉัน:

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.