【Leetcode】Restore IP Addresses

题目链接:https://leetcode.com/problems/restore-ip-addresses/
题目:

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

For example:
Given "25525511135",

return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)

思路:

考虑本题和https://leetcode.com/problems/palindrome-partitioning/  几乎一样,那道题我没做出来,超时了。。。拿过来稍加改动结果AC了。

思路就是,把这道题看成是在1~str.length()之间选择大小为3的子集,我们把该子集作为切分字符串的方案,然后对字符串做相应的切分并判断是否符合ip地址特点。所以本算法分三个部分,子集生成、切分字符串、判断是否符合ip地址的特点。其中子集生成算法实质就是 Combinations


看了别人的题解,发现我的方法虽然思路直观,但实现麻烦,主要是切分字符串要考虑的细节比较多,在实际笔试中可能没那么多时间做出来。

更简洁、值得学习的方法参考 http://blog.csdn.net/linhuanmars/article/details/24683699

算法:

	List<String> r = new ArrayList<String>();// 符合ip特点的切分结果
	List<List<Integer>> iLists = new ArrayList<List<Integer>>();// 切分方案
	List<Integer> list = new ArrayList<Integer>();
	String str = "";// 切分字符串用
	int length = 0;// 字符串长度

	public List<String> restoreIpAddresses(String s) {
		this.length = s.length();
		if (length > 12 || length < 4) {// ip字符串最大12位,最小4位
			return r;
		}
		this.str = s;
		dspPartition(1);// 生成切分方案
		cutStr();// 按照生成的切分方案来切分字符串,并判断是否是ip地址
		return r;
	}

	void dspPartition(int cur) { // 这里的切分方案实质是求在[1~k]之间求一个大小为3的子集
		if (cur > length) {
			return;
		} else if (list.size() == 3) { // ip地址有四个部分,3个切分点
			iLists.add(new ArrayList<Integer>(list));
		} else {
			for (int i = cur; i <= length; i++) {
				list.add(i);
				dspPartition(i + 1);
				list.remove(list.size() - 1);
			}
		}
	}

	public void cutStr() {
		for (int i = 0; i < iLists.size(); i++) {
			List<Integer> list = iLists.get(i);
			boolean flag = true;
			List<String> strs = new ArrayList<String>();// 暂存切分结果
			if (list.size() != 0) {
				for (int j = 0; j < list.size(); j++) {// 对每种切分方案切分字符串
					String tmp = "";
					if (j == 0) {// 0~j
						tmp = str.substring(0, list.get(j));
						if (!isIpNode(tmp)) {
							flag = false;
						}
						strs.add(tmp);
					}
					if (j - 1 >= 0) {// j-1 ~j
						tmp = str.substring(list.get(j - 1), list.get(j));
						if (!isIpNode(tmp)) {
							flag = false;
						}
						strs.add(tmp);
					}
					if (j == list.size() - 1) {// j~~
						tmp = str.substring(list.get(j), str.length());
						if (!isIpNode(tmp)) {
							flag = false;
						}
						strs.add(tmp);
					}

				}
			}
			if (flag) {// 按此种切分方案切分的ip每个部分都满足ip地址特点
				String s = "";
				for (int d = 0; d < strs.size() - 1; d++) {
					s += strs.get(d) + ".";
				}
				s += strs.get(strs.size() - 1);
				r.add(s);
			}
		}
	}

	boolean isIpNode(String s) {
		if (s.length() > 3) // ip地址长度最大是3位
			return false;
		if (s.charAt(0) == '0' && s.length() > 1) { // 0开头且长度大于1的字符串是非法的
			return false;
		}
		if (Integer.parseInt(s) <= 255) // ip地址最大为255
			return true;
		else
			return false;
	}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值