-
Notifications
You must be signed in to change notification settings - Fork 1
/
Next Permutation
78 lines (68 loc) · 1.84 KB
/
Next Permutation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#else
#define FORCE_INLINE __attribute__((always_inline)) inline
#endif
FORCE_INLINE static void swap(int *restrict v1, int *restrict v2)
{
int tmp = *v1;
*v1 = *v2;
*v2 = tmp;
}
static int quicksortCompare(const void *v1, const void *v2)
{
return *(int *)v1 - *(int *)v2;
}
static int splitArray(int *nums, int numsSize)
{
for (int right = numsSize - 1; right >= 1; right--)
if (nums[right] > nums[right - 1])
return right;
return 0;
}
static int searchMinValueIdx(int *restrict nums, int numsSize, int leftIdx, int rightIdx)
{
const int pivot = nums[leftIdx];
int minVal = INT_MAX, minValIdx = -1;
for (; rightIdx < numsSize; rightIdx++)
{
if (nums[rightIdx] > pivot && nums[rightIdx] < minVal)
{
minVal = nums[rightIdx];
minValIdx = rightIdx;
}
}
return minValIdx;
}
static bool __nextPermutation(int *nums, int numsSize)
{
if (numsSize <= 1)
return false;
const int rightArrayIdx = splitArray(nums, numsSize);
if (rightArrayIdx == 0 && numsSize > 0)
{
return __nextPermutation(nums + 1, numsSize - 1);
}
else
{
const int leftArrayIdx = rightArrayIdx - 1;
const int minValIdx = searchMinValueIdx(nums, numsSize, leftArrayIdx, rightArrayIdx);
swap(&nums[leftArrayIdx], &nums[minValIdx]);
qsort(nums + rightArrayIdx, numsSize - rightArrayIdx, sizeof(nums[0]), quicksortCompare);
}
return true;
}
void nextPermutation(int *nums, int numsSize)
{
if (numsSize > 1)
{
if (__nextPermutation(nums, numsSize) == false)
{
qsort(nums, numsSize, sizeof(nums[0]), quicksortCompare);
}
}
}