LintCode-862:Next Closest Time (DFS 搜索经典题)

这题给我感觉更有点像组合类的搜索。
要注意的地方有:
1)时间的比较最好先换成int,再来比较。
2)closet time可以大于,也可以小于原时间。比如说”23:59”的closet time是”22:22“, 这里closet time实际上是可以小于原时间的,因为是第二天的时间了。
那么怎么比较两个solution那个更好呢?比如说”13:32”,怎么比较”13:33”和”12:33” 哪个更好?这里时间差有正有负。
这里有个技巧就是把solution和original的差(不管是正的还是负的)先加上一天的时间(+24*60)再取模(%(24*60))。也就是(time_sol - time_orig + 24 * 60) % (24 * 60);

这样”13:33”算下来是 1 minutes, 而”12:33”算下来就很大了。

3)注意剪枝

class Solution {
public:
    /**
     * @param time: the given time
     * @return: the next closest time
     */
    string nextClosestTime(string &time) {
        vector<int> origTimeVec = {time[0] - '0', 
                                   time[1] - '0', 
                                   time[3] - '0',
                                   time[4] - '0'};

        origTimeInt = toTimeInt(origTimeVec);
        bestSolInt = origTimeInt;
        vector<int> solVec;
        helper(0, origTimeVec, solVec);

        string hiSol = to_string(bestSolInt / 60);
        if (bestSolInt / 60 < 10) 
            hiSol = "0" + hiSol;

        string miSol = to_string(bestSolInt % 60);
        if (bestSolInt % 60 < 10)
            miSol = "0" + miSol;

        return hiSol + ":" + miSol;
    }

    void helper(int index, vector<int> &origTimeVec, vector<int> &solVec) {  
        if (index == 4) {
            int hr = solVec[0] * 10 + solVec[1];
            if (hr > 23) return; //剪枝

            int mi = solVec[2] * 10 + solVec[3];
            if (mi > 59) return; //剪枝 

            int solInt = toTimeInt(solVec);
            if (timeDiff(solInt, origTimeInt) < timeDiff(bestSolInt, origTimeInt)) {
                bestSolInt = solInt;
            }
            return;
        }

        for (int i = 0; i < 4; ++i) {
            solVec.push_back(origTimeVec[i]);
            helper(index + 1, origTimeVec, solVec);
            solVec.pop_back();
        }
    }


private:
    int origTimeInt;
    int bestSolInt;
    int toTimeInt(vector<int> &timeVec) {
        int h = timeVec[0] * 10 + timeVec[1];
        int m = timeVec[2] * 10 + timeVec[3];
        return h * 60 + m;
    }

    int timeDiff(int time1, int time2) {
        if (time1 == time2) {
            return 24 * 60;
        } else {
            return (time1 - time2 + 24 * 60) % (24 * 60);  //重要技巧!!!
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值