回溯算法(记录)

要点一:模板;(组合类)

int *path;
int top;
int **ans;

breacktor(int n; int *nums, int numsSize)
{
    //插入条件。
    if()
    {
        
    }
    //核心语句
    for(int i=n; i<numsSize; i++)
    {
        path[top++] = nums[i];
        breacktor(i+1, nums, numsSize);
        top--;
    }
}

回溯巧妙应用(力扣递增子序)

    if(nums[cur] >= last)
    {
        temp[tempSize++] = nums[cur];
        dfs(cur + 1, nums[cur], nums, numsSize, returnColumnSizes);
        //不会让多余的数留在数组里的
        tempSize--;
    }
    //只要不等于最小数就另开连锁,最开始必然是最小的。
    if(nums[cur] != last)
    {
        dfs(cur + 1, last, nums, numsSize, returnColumnSizes);
    }

回溯去重

在核心语句前,让每个子序只出现一个相同元素

    for(j=n; j<len; j++)
    {
        while(j < len-1 && candidates[j] == candidates[j+1])
        {
            j++;
        }
        path[top++] = candidates[j];
        sum = sum + candidates[j];
        beacktork(j+1, target, sum, candidates, candidates, returnSize,returnColumnSizes);
        sum = sum - candidates[j];
        top--;
        
    }

在核心语句后,让数组每个相同元素只执行一次

    for(j=n; j<numsSize; j++)
    {
        
        path[top++] = nums[j];
        breaktor(j+1, nums, numsSize, returnSize, returnColumnSizes);
        top--;
        while((j < numsSize-1) && (nums[j] == nums[j+1]))
        {
            j++;
        }
    }

模板(排序类一)(swap+去重)


bool isHaveSame(int * nums,int indexleft,int indexRight)
{
    while (indexleft < indexRight) 
    {
        if (nums[indexleft] == nums[indexRight])
            return true; 
        indexRight--;
    }
    return false;
}


void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
    return;
}

void bracktor(int n, int *nums, int numsSize, int*returnSize, int **returnColumnSizes)
{
    if(n == numsSize)
    {
        ans[*returnSize] = (int *)malloc(sizeof(int) *numsSize);
        for(int i=0; i<numsSize; i++)
        {
            ans[(*returnSize)][i] = nums[i];
        }
        (*returnColumnSizes)[(*returnSize)] = numsSize;
        (*returnSize)++;
        return;
    }
    int j;
    for(j=n; j<numsSize; j++)
    {
        if(!isHaveSame(nums,j,numsSize-1) )
        {
            swap(nums+j, nums+n);
            bracktor(n+1, nums, numsSize, returnSize, returnColumnSizes);
            swap(nums+j, nums+n);
        }
    }
}

模板(排序类二)(数组标志位+去重)

先排序,每层遍历从头开始,已用数据(vis[i] == 1)跳过,当前数据与之前或之后比较,数值相同且都未被使用则跳过。

int* vis;

void backtrack(int* nums, int numSize, int** ans, int* ansSize, int idx, int* perm) {
    if (idx == numSize) {
        int* tmp = malloc(sizeof(int) * numSize);
        memcpy(tmp, perm, sizeof(int) * numSize);
        ans[(*ansSize)++] = tmp;
        return;
    }
    for (int i = 0; i < numSize; ++i) {
        if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
            continue;
        }
        perm[idx] = nums[i];
        vis[i] = 1;
        backtrack(nums, numSize, ans, ansSize, idx + 1, perm);
        vis[i] = 0;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations-ii/solution/quan-pai-lie-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值