题目
难度:★★★☆☆
类型:字符串
方法:深度优先搜索
题目
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
解答
有几种不同的办法解决这个问题。
方法1:笨办法,遍历
字符串中总共要被分割为4个部分,找到满足条件的分割可能性。
我们定义这四个部分分别是a,b,c和d,定义一个函数is_valid用来判断一个子串是否可以作为ip地址的一个部分,有两种情况,当只含有一个字符时,一定可以作为ip地址的一个部分,当不小于一个字符时,需要第一个字符不能为零,且整体字符转为数字的数值不能超过255。
从头开始遍历,要注意遍历的过程的始末条件,设i,j,k为三个分割点,根据这三个分割点实现嵌套循环,每个元素从1位到3位依次遍历,通过移动分割点的位置即可,当分割出来的元素不满足条件时,即可放弃这种方式。
class Solution1:
def restoreIpAddresses(self, s):
ans = []
n = len(s)
def is_valid(num):
return len(num) == 1 or (len(num) > 1 and num[0] != "0" and int(num) <= 255)
for i in range(0, min(3, n-3)):
a = s[:i+1]
if not is_valid(a):
break
for j in range(i+1, min(i+4, n-2)):
b = s[i+1:j+1]
if not is_valid(b):
break
for k in range(j+1, min(j+4, n-1)):
c = s[j+1:k+1]
d = s[k+1:]
if not is_valid(c):
break
if not is_valid(d):
continue
ans.append("{}.{}.{}.{}".format(a, b, c, d))
return ans
方法2:深度优先搜索
推荐这种方法。深度优先遍历可以通过递归实现,但是要在函数开头写清楚终止条件,定义函数,函数输入为剩余的字符串,当前的结果以及当前的分割列表,分别用s,res和path表示,本例的终止条件为剩余字符串s变成空字符串,且分割列表path中的元素正好含有4个,终止时需要将当前结果保留在结果列表res中。
如果当前不满足终止条件,需要进行遍历,遍历的对象是新增的单元,长度从1到3,但是在每次循环开始时,需要判断一下当前s中剩下的元素够不够新增单元的长度,如果不够,那么直接退出所有循环即可,通过这样的操作将结果可能性进行减枝。
深度优先搜索的条件是,当当前选中的单元满足成为ip地址一个部分的条件时,可以调用本函数进行深度优先搜索,这时的s应该为去掉本单元后剩余的字符串,res延续原来的数值,path中添加当前找到的单元。
class Solution:
def restoreIpAddresses(self, s):
def dfs(s, res, path):
if not s and len(path) == 4:
res.append('.'.join(path))
return
for i in range(1, 4):
if i > len(s):
break
num = int(s[:i])
if num <= 255:
dfs(s[i:], res, path + [s[:i]])
if len(s) < 4 or len(s) > 12:
return []
res = []
path = []
dfs(s, res, path)
return res
如有疑问或建议,欢迎评论区留言~