LeetCode刷题笔记- 46.全排列

LeetCode刷题笔记- 46.全排列

    • 思想
      • C代码
      • 注意点
      • 执行结果

思想

使用数组里的数字,看成n位的10进制数,然后从小到大进行数数;

C代码

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int comp(const void *a, const void *b) {
    return *((int *)a) - *((int *)b);
}
void swap(int *nums, int a, int b) {
    nums[a] ^= nums[b];
    nums[b] ^= nums[a];
    nums[a] ^= nums[b];
}
int* copy_arr(int *nums, int numsSize) {
    int *ret = NULL;
    if (numsSize <= 0) {
        return NULL;
    }
    ret = calloc(numsSize, sizeof(int));
    memcpy(ret, nums, sizeof(int) * numsSize);
    return ret;
}
int find_idx(int *nums, int numsSize, int *s, int *e) {
    int si, ei;
    if(numsSize <= 1) {
        return -1;
    }
    ei = numsSize - 1;
    si = numsSize - 2;

    while(1) {
        if(si < 0 || ei < 1)
            break;
        if(nums[si] >= nums[si+1]) {
            si--;
            continue;
        }
        if(nums[ei] <= nums[si]) {
            ei--;
            continue;
        }
        *s = si;
        *e = ei;
        return 0;
    }
    return -1;
}
int* find_next(int *nums, int numsSize) {
    int s,e;
    int *ret = NULL;

    if(find_idx(nums, numsSize, &s, &e) == -1) {
        return NULL;
    }
    ret = copy_arr(nums, numsSize);
    swap(ret, s, e);
    qsort(ret+s+1, numsSize-s-1, sizeof(int), comp);
    return ret;
}
int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int **ret = NULL;
    int *t = NULL;
    int listSize = 1 << 4;
    int ls = 1;
    int i;

    ret = calloc(listSize, sizeof(int *));
    qsort(nums, numsSize, sizeof(int), comp);
    ret[ls-1] = nums;
    t = nums;
    while(1) {
        t = find_next(t, numsSize);
        if( t == NULL)
            break;
        ls++;
        if(ls > listSize - 4) {
            listSize = listSize << 1;
            ret = realloc(ret, listSize * sizeof(int *));
        }
        ret[ls-1] = t;
    }
    *returnSize = ls;
    *returnColumnSizes = calloc(ls, sizeof(int));
    for(i = 0; i < ls; i++) {
        (*returnColumnSizes)[i] = numsSize;
    }
    return ret;
}

注意点

  1. 数字从小到大排,所以开始find_idx()函数里面的si应该是找第一个顺序对,即nums[si]>=nums[si+1]时说明可以跳过si;
  2. 注意遍历过程中,上一个数组的保留,因为上一个数组的结果是下一个迭代的入参,这样避免重复输入nums初始值导致死循环超时;

执行结果

LeetCode刷题笔记- 46.全排列_第1张图片

你可能感兴趣的:(算法刷题,leetcode,c语言,算法)