【LeetCode】93. Restore IP Addresses 解题报告(Python & C++)

901 篇文章 204 订阅

作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/restore-ip-addresses/description/

题目描述

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

Example:

Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"]

题目大意

题目中给了一个仅有数字组成的字符串,要求这个字符串能构成的合法IP组合。

解题方法

回溯法

我是按照Tag刷的,当然知道这个题是回溯法了。。其实只要看到所有的组合,一般都是用回溯。

第一遍超时,原因是没有找到合理的剪枝!!这就是回溯法最难的地方:剪枝!

当然了,看出了测试用例是一个特别长的由1组成的字符串,仅仅这一个测试用例超时,所以我加上了len(s)和12的判断就ok了。所以有了下面的版本:

代码如下:

class Solution(object):
    def restoreIpAddresses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        if len(s) > 12:
            return []
        res = []
        self.dfs(s, [], res)
        return res
        
    def dfs(self, s, path, res):
        if not s and len(path) == 4:
            res.append('.'.join(path))
            return
        for i in range(1, 4):
            if i > len(s):
                continue
            number = int(s[:i])
            if str(number) == s[:i] and number <= 255:
                self.dfs(s[i:], path + [s[:i]], res)

看到了题目中有别的同学的剪枝方法特别好,那就是每次dfs的时候都去检查一下所有的字符串的长度是不是能满足在最多4个3位数字组成,果然速度提升了很多:

class Solution(object):
    def restoreIpAddresses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        res = []
        self.dfs(s, [], res)
        return res
        
    def dfs(self, s, path, res):
        if len(s) > (4 - len(path)) * 3:
            return
        if not s and len(path) == 4:
            res.append('.'.join(path))
            return
        for i in range(min(3, len(s))):
            curr = s[:i+1]
            if (curr[0] == '0' and len(curr) >= 2) or int(curr) > 255:
                continue
            self.dfs(s[i+1:], path + [s[:i+1]], res)

二刷的时候,使用的C++,同样需要使用合理的剪枝,提交的时候有一次WA,原因是没有考虑0开头的整数是不合法的。代码如下:

class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        if (s.size() > 12) return {};
        vector<string> res;
        helper(s, res, {}, 0);
        return res;
    }
    void helper(const string& s, vector<string>& res, vector<string> path, int start) {
        if (start > s.size() || path.size() > 4) return;
        if (start == s.size() && path.size() == 4) {
            res.push_back(path[0] + '.' + path[1] + '.' + path[2] + '.' + path[3]);
            return;
        }
        for (int i = 1; i <= 3; i++) {
            string sub = s.substr(start, i);
            if (sub.size() == 0 || (sub.size() > 1 && sub[0] == '0') || stoi(sub) > 255) continue;
            path.push_back(sub);
            helper(s, res, path, start + i);
            path.pop_back();
        }
    }
};

日期

2018 年 6 月 11 日 —— 今天学科三在路上跑的飞快~
2018 年 12 月 22 日 —— 今天冬至

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
你好!对于LeetCode上的问题994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍历整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍历当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍历四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍历完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍历橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值