题目:
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。 给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法:
方法一 暴力解法
func restoreIpAddresses(s string) []string {
if len(s) == 0 {
return nil
}
length := len(s)
ans := make([]string, 0)
iStart := 0
for i := 0; i < 3 && i < length; i ++ {
if !validate(s[iStart:i + 1]) {
continue
}
str := s[iStart:i + 1]
jStart := i + 1
for j := i + 1; j <= i + 3 && j < length; j ++ {
if !validate(s[jStart:j + 1]) {
continue
}
// 这里要重新初始化变量,否则会和上次循环的secStr拼接在一起
secStr := str + "." + s[jStart:j + 1]
kStart := j + 1
for k := j + 1; k <= j + 3 && k < length; k ++ {
if !validate(s[kStart:k + 1]) || !validate(s[k + 1:length]) {
continue
}
// 这里要重新初始化变量,否则会和上次循环的finalStr拼接在一起
finalStr := secStr + "." + s[kStart:k + 1] + "." + s[k + 1:length]
ans = append(ans, finalStr)
}
}
}
return ans
}
// 判断字符串是否在范围[0:255]
func validate(str string) bool {
if len(str) == 0 {
return false
}
if str== "0" {
return true
}
if str[0] == '0' {
return false
}
n, _ := strconv.Atoi(str)
return 0 <= n && n <= 255
}
方法二 回溯
import "strings"
var segments []string
var maxSegId = 3
var ans []string
func restoreIpAddresses(s string) []string {
if len(s) == 0 {
return nil
}
segments = make([]string, 4)
ans = make([]string, 0)
dfs(s, 0, 0)
return ans
}
func dfs(s string, segId, segStart int) {
// 填充完毕,返回
if segId == 4 {
return
}
// 遍历到IP的最后8位了
if segId == maxSegId {
if validate(s[segStart:len(s)]) {
// 回溯的精髓在这里,设置segments[segId]
segments[segId] = s[segStart:len(s)]
ans = append(ans, strings.Join(segments, "."))
}
}
// 当前位等于‘0’
if s[segStart:len(s)] == "0" {
segments[segId] = "0"
dfs(s, segId + 1, segStart + 1)
}
// 遍历
for end := segStart ; end <= segStart + 2 && end < len(s); end ++ {
curStr := s[segStart: end + 1]
if !validate(curStr) {
continue
}
segments[segId] = curStr
dfs(s, segId + 1, end + 1)
}
}
// [0:255]
func validate(str string) bool {
if len(str) == 0 {
return false
}
if str== "0" {
return true
}
if str[0] == '0' {
return false
}
n, _ := strconv.Atoi(str)
return 0 <= n && n <= 255
}