LeetCode1079. 活字印刷 ( DFS , 回溯 )

本文介绍了一种使用深度优先搜索(DFS)和回溯法解决力扣(LeetCode)上的组合计数问题。题目要求从给定字符串tiles中找出所有可能的不重复子串组合。通过标记已使用的字符并利用unordered_set进行去重,可以得到所有可能的组合,并返回组合的总数。算法复杂度为O(N^N),其中N为tiles的长度。
摘要由CSDN通过智能技术生成

力扣

                                                         

解题思路:

此题组合的长度不唯一,最小组合长度为 1 , 最大组合长度为 tiles 的长度。
按照题意 tiles 中每一个位置的字符在组合中只能出现一次, 所以可以用一个标记辅助
当去组合新的组合时,可以与 tiles 中的每一个位置组合,但是如果当前位置已经在当前组合中出现过,则跳过 虽然此题中每一个位置的字符在组合中只能出现一次,但是tiles 中可能有相同的字符,所以需要考虑重复的组合 而unordered_set 可以天然去重,可以用其去重。
                                        
DFS + 回溯:
1. 当前组合不为空 , 则插入 set
2. 继续给当前组合拼接新的组合,尝试拼接 tiles 每一个位置的字符
3. 如果当前位置已在组合中出现过,返回到 2 ,否则标记当前位置,继续拼接更长的组合
4. 回溯,尝试组合其它位置,返回 2
当所有位置都已经使用过时,当前递归就结束了,继续向上层 DFS 回退
最终返回 set 的大小即为组合数目。
                                        

                        

class Solution {
public:
    void DFS(string& tiles , string curstr , unordered_set<string>& allRet , vector<int>& book)
    {
        if(!curstr.empty()) //新的组合插入到 allRet中
        {
          allRet.insert(curstr);
        }

        for(int i = 0 ; i < tiles.size() ; ++i)
        {
            if(book[i] == 0) //当前字符未被用过
            {
                book[i] = 1; //设置用过
                DFS(tiles , curstr + tiles[i] , allRet , book);
                book[i] = 0;  //回溯
            }
        }
    }

    int numTilePossibilities(string tiles) 
    {
       if(tiles.size() == 1)
       return 1;

       unordered_set<string> allRet; //去重

       vector<int> book(tiles.size() , 0); //标记

       DFS(tiles , "" , allRet , book);

    return allRet.size();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值