Skip to content

Commit

Permalink
feat: add next permutation problem (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
jafar75 authored May 9, 2024
1 parent 833a3e5 commit 2354582
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.

1. [`GenerateElementSet`](./math/permutation/heaps.go#L37): No description provided.
2. [`Heaps`](./math/permutation/heaps.go#L8): Heap's Algorithm for generating all permutations of n objects
3. [`NextPermutation`](./math/permutation/next_permutation.go#8): A solution to find next permutation of an integer array in constant memory

---
</details><details>
Expand Down
37 changes: 37 additions & 0 deletions math/permutation/next_permutation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// A practice to find lexicographically next greater permutation of the given array of integers.
// If there does not exist any greater permutation, then print the lexicographically smallest permutation of the given array.
// The implementation below, finds the next permutation in linear time and constant memory and returns in place
// Useful reference: https://www.geeksforgeeks.org/next-permutation/

package permutation

func NextPermutation(nums []int) {
pivot := 0
for pivot = len(nums) - 2; pivot >= 0; pivot-- {
if nums[pivot] < nums[pivot+1] {
break
}
}
if pivot < 0 {
// current permutation is the last and must be reversed totally
for l, r := 0, len(nums)-1; l < r; l, r = l+1, r-1 {
nums[l], nums[r] = nums[r], nums[l]
}
} else {
succ := 0
for succ = len(nums) - 1; succ > pivot; succ = succ - 1 {
if nums[succ] > nums[pivot] {
break
}
}

// Swap the pivot and successor
nums[pivot], nums[succ] = nums[succ], nums[pivot]

// Reverse the suffix part to minimize it
for l, r := pivot+1, len(nums)-1; l < r; l, r = l+1, r-1 {
nums[l], nums[r] = nums[r], nums[l]
}
}

}
40 changes: 40 additions & 0 deletions math/permutation/next_permutation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package permutation

import (
"reflect"
"testing"
)

func TestNextPermutation(t *testing.T) {
var nextPermutationTestData = []struct {
description string
numbers []int
next []int
}{
{
description: "Basic case",
numbers: []int{1, 2, 3},
next: []int{1, 3, 2},
},
{
description: "Should reverse the whole slice",
numbers: []int{3, 2, 1},
next: []int{1, 2, 3},
},
{
description: "A more complex test",
numbers: []int{2, 4, 1, 7, 5, 0},
next: []int{2, 4, 5, 0, 1, 7},
},
}
for _, test := range nextPermutationTestData {
t.Run(test.description, func(t *testing.T) {
NextPermutation(test.numbers)

if !reflect.DeepEqual(test.numbers, test.next) {
t.Logf("FAIL: %s", test.description)
t.Fatalf("Expected result:%v\nFound: %v", test.next, test.numbers)
}
})
}
}

0 comments on commit 2354582

Please sign in to comment.