Next Permutation

// 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
// time complexity: O(n)
// space complexity: O(1)
// 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]
		}
	}

}