leetcode算法入门系列学习11(递归 / 回溯)『 组合 | 全排列 | 字母大小写全排列 』

【= 组合 =】

题目描述

传送门

解题思路

求得n个数中k个数的组合集合
关于题解 可以参考这个
🙃🙃🙃 关于回溯算法 你该了解这些!!!

解题方法

  • PHP
 function combine($n, $k) {
    $result = []; 
    $this->backtrack($n,$k,1,[], $result);
    return $result;
 }

 function backtrack($n,$k,$start,$path,&$result) {
    if(count($path) == $k) {
        $result[] = $path;
        return;
    }
    //剪枝:如果循环起始位置之后的个数已经不满足我们需要的个数了
    //就没必要在继续检索了,减少不必要的循环
    for ($i=$start;$i<=$n-($k-count($path))+1;$i++) {
        $path[] = $i;
        $this->backtrack($n,$k,$i+1,$path,$result);
        array_pop($path);
    }
 }

在这里插入图片描述

  • GO
var res [][]int

func combine(n int, k int) [][]int {
	res = [][]int{}
	backtrack(n, k, 1, []int{})
	return res
}

func backtrack(n, k, start int, path []int) {
	if len(path) == k {
		temp := make([]int, k)
		copy(temp, path)
		res = append(res, temp)
		return
	}
	for i := start; i <= n-(k-len(path))+1; i++ {
		path = append(path, i)
		backtrack(n, k, i+1, path)
		path = path[:len(path)-1]
	}
}

在这里插入图片描述

[= 全排列 =]

题目描述

传送门

解题思路

经典回溯算法题:相较于上题较简单
回溯中参数为原始数组nums,以及当前数组arr
回溯的终止条件为,当前arr的个数已经等于原始数组nums
回溯的处理,循环遍历原始数组nums,当前值不存在arr中时,将该值放入arr中,递归调用
由于上面的行为会找到最终答案,所以,在处理完上面请求时,将arr进行出栈操作,继续遍历

解题方法

  • PHP

function permute($nums) {
    $res = [];
    $this->backtrack($nums,[],$res);
    return $res;
}

function backtrack($nums, $arr, &$res) {
    if(count($arr) == count($nums)) {
        $res[] = $arr;
        return; 
    }
    foreach($nums as $v) {
        if(!in_array($v,$arr)) {
            $arr[] = $v;
            $this->backtrack($nums, $arr, $res);
            array_pop($arr);
        }
    }
}

在这里插入图片描述

  • GO
var res [][]int
func permute(nums []int) [][]int {
    res = [][]int{}
	backtrack(nums,len(nums), []int{})
	return res
}

func backtrack(nums[]int, numLen int, path []int) {
	if len(nums)==0{
		temp := make([]int, len(path))
		copy(temp, path)
		res = append(res, temp)
		return
	}
	for i:=0;i<numLen;i++ {
		cur :=nums[i]
		path = append(path,cur)
		nums = append(nums[:i],nums[i+1:]...)
		backtrack(nums, len(nums), path)
		nums = append(nums[:i], append([]int{cur},nums[i:]...)...)
		path = path[:len(path)-1]
	}
}

在这里插入图片描述

[= 字母大小写全排列 =]

题目描述

传送门

解题思路

1、从左往右依次遍历字符
2、判断是否为数字。如果是数字则直接拼接
3、如果是字母,将当前遍历过的字符串复制两份,第一份末尾添加lowercase(s),第二份末尾拼接upper(s)

解题方法

  • PHP
private $res = [];

/**
 * @param String $s
 * @return String[]
 */
function letterCasePermutation($s) {
    $this->back($s, 0, "", strlen($s));
    return $this->res;
}

function back($s, $start, $temp, $len) {
    for($j=$start; $j<$len; $j++) {
        if(is_numeric($s[$j])) {
            // 是数字
            $temp .= $s[$j];
        } else {
            // 是字母
            if(strtolower($s[$j]) == $s[$j]) {
                // 小写->大写
                $this->back($s,$j+1, $temp . strtoupper($s[$j]), $len);
            } else {
                // 大写->小写
                $this->back($s, $j+1, $temp . strtolower($s[$j]), $len);
            }
            $temp .= $s[$j];
        }
    }
    if(strlen($temp) == $len) $this->res[] = $temp;
}

在这里插入图片描述

  • GO
func letterCasePermutation(s string) []string {
    res := []string{""}
	for i := 0; i < len(s); i++ {
		if (s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z') {
            // 是字母
			tmp := make([]string, len(res))
			//复制当前数组
			copy(tmp, res)
			for j, _ := range res {
				res[j] = res[j] + strings.ToLower(string([]byte{s[i]}))
				tmp[j] = tmp[j] + strings.ToUpper(string([]byte{s[i]}))
			}
			res = append(res, tmp...)
		} else {
			//如果是数字,则直接再末尾加上该数字即可
			for j, _ := range res {
				res[j] = res[j] + string([]byte{s[i]})
			}
		}
	}
	return res
}

在这里插入图片描述== 终于 ~~~完成了 ~~~== 🤪🤪🤪🤪🤪🤪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bennett_G

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值