LintCode-570: Find the Missing Number II (DFS经典题)

这题跟简单的找missing number (用XOR)的完全没关系,因为每次划分子字符串可以是1-2个字符,只能用DFS。
我的方法是用的经典的DFS回溯。

代码如下:

class Solution {
public:
    /**
     * @param n: An integer
     * @param str: a string with number from 1-n in random order and miss one number
     * @return: An integer
     */
    bool findIt = false; 
    int g_missingNum;

    int findMissing2(int n, string &str) {
        vector<int> visited(n+1, 0);
        helper(n, str, 0, visited);
        return g_missingNum;
    }

    void helper(int n, string &str, int index, vector<int>& visited) {
        if (index == str.size()) {
            if (findIt) return;

            int missingCount = 0;
            int missingNum;
            for (int i = 1; i <= n; ++i) {
                if (!visited[i]) {
                    missingCount++;
                    missingNum = i; 
                }
            }

            if (missingCount == 1) {
                findIt = true;
                g_missingNum = missingNum;
            }
            return;
        }

        for (int i = 1; i <= 2; ++i) {
            if (index + i <= str.size()) {
                int candidateNum = stoi(str.substr(index, i));

                if ((candidateNum <= 0) || (candidateNum > n) || 
                     visited[candidateNum] ||    //no duplicate numbers
                     (str.substr(index, i)[0] == '0')     //do not consider '0' or '09'
                    ) continue;  //剪枝 

                visited[candidateNum] = 1;
                helper(n, str, index + i, visited);
                visited[candidateNum] = 0;
            }
        }
    }
};

注意:
1)要剪枝,不然超时
2)要用visited[]数组,并且要注意避免重复。我之前准备用一个set来存储每次的结果,把所有的结果都放到一个二维vector里面,那样可能也可以,但是没有这个visited[]数组来得简单,这里连二维数组也不用,因为只要找到一个解就可以,后面的都不用做了。
之前的那个subset 和 Split String 的题为什么要用一个二维vector来存results呢?因为那两题需要得到所有的解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值