day28回溯法4-IP地址&子集问题

文章介绍了如何使用回溯算法解决复原IP地址和子集问题。在复原IP地址问题中,通过递归函数判断子串合法性,当逗点数量达到3时返回结果。子集问题则在每层递归中收集结果,避免重复选择同一层的元素。对于子集II问题,处理了在同一层不能有重复元素的情况。
摘要由CSDN通过智能技术生成

前言:复习回溯算法

回溯算法的主要结构:
递归函数
if(终止条件)
for(遍历各个子节点){
处理结点
递归函数
撤销结点
}

93.复原IP地址

在这里插入图片描述

  1. 如何描述切割垫
  2. 怎样对子串的合法性进行判断
  3. 当pointSum==3的时候终止条件,对函数的值进行返回操作;其他更加复杂的不需要进行考虑,
vector<string> result;
void backtracking(s,startIndex,pointSum) // startIndex:确定下一层循环从字符串的那边开始取值;pointSum通过逗点的数量决定树的深度
	//  如果有三个逗点,四个字符串就可以返回这个子字符串
	if(pointSum == 3){
		if(isValid(s,startIndex,s.size-1)){//用来判断这个子串是否和合法,最后一段合法那么收集这个结果
			result.popback(s)
			return 
			}
	}
	for(i=startIndex,i<=s.size,i++){
		// 切割之后对切割的子串进行合法性判断,区间是本题的难点所在
		if(isValid(s,startIndex,i)){
			// 合法性的判断完成之后,需要进行插入的操作
			path
			pointSum += 1
			backtracking(s,i+2,pointSum) // 给字符串加了逗点所以需要记性i+2
			s.erase
			pointSum -= 1
		}
	}
	
class Solution:
    def __init__(self):
        self.result = []
        self.path = []
    def isValid(self,s,left,right): 
        if (int(s[left:right]) <= 255 and  int(s[left:right]) >= 0 and s[left] != '0') or (s[left:right] == '0') :
            return True 
        return False
    def restoreIpAddresses(self, s: str) -> List[str]:
        # 类似于回文子串,对字符串进行分割
        def backtracking(startIndex):
            # 终止条件时逗点为3时候的值
            if startIndex == len(s) and len(self.path) == 4:
                self.result.append('.'.join(self.path.copy()))
                return 
            for i in range(startIndex,len(s)):
                if len(self.path) > 3:
                    break
                if self.isValid(s,startIndex,i+1):
                    print(self.path,startIndex,i+1)
                    self.path.append(s[startIndex:i+1])   
                    backtracking(i+1)
                    self.path.pop()
        backtracking(0)
        return self.result

78.子集

在这里插入图片描述

  • 子集问题和组合问题的不同之处,组合和分割字符串都是在终止条件处收集结果,但是子集问题每一层递归得到的结果都要放在结果集中。
path
result
void backtracking(nums,startIndex){
	result.append(path)  // 因为每一次递归都需要将当前结果存储进入result数组中
	// 叶子结点的剩余数组都是空的状态,整体的叶子结点的情况
	if(startIndex >= nums.size){
		return 
	}
	for(i=startIndex;i<nums.size;i++){
		path.pushback(nums[])
		backtracking(nums,i+1)
		path.pop.back()
	}
}
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result = []
        path = []
        def backtracking(startIndex):
            result.append(path.copy())
            if startIndex >= len(nums):
                return
            for i in range(startIndex,len(nums)):
                path.append(nums[i])
                backtracking(i+1)
                path.pop()
        backtracking(0)
        return result

90.子集II

同一个树枝上可以重复选2,同一个树层上不可以重复选2

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        result = []
        path = []
        nums = sorted(nums)
        def backtracking(startIndex):
            if startIndex > len(nums):
                return
            result.append(path.copy()) 
            for i in range(startIndex,len(nums)):
           		# for循环决定树层的结构,树层维度上不要有相同的值即可。
                if i > startIndex and nums[i] == nums[i-1]:
                    continue
                path.append(nums[i])
                backtracking(i+1)
                path.pop()
        backtracking(0)
        return result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值