LeetCode093 Restore IP Addresses

详细见:leetcode.com/problems/restore-ip-addresses


Java Solution: github

package leetcode;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

/*
 * 	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)
 */


public class P093_RestoreIPAddresses {
	public static void main(String[] args) {
//		List<String> ans = new Solution2().restoreIpAddresses("25525511135");
		List<String> ans = new Solution2().restoreIpAddresses("2552552563");
//		List<String> ans = new Solution2().restoreIpAddresses("255255255255");
//		List<String> ans = new Solution2().restoreIpAddresses("1231231231");
//		List<String> ans = new Solution2().restoreIpAddresses("1234");
//		List<String> ans = new Solution2().restoreIpAddresses("0000");
//		List<String> ans = new Solution2().restoreIpAddresses("11234");
//		List<String> ans = new Solution2().restoreIpAddresses("010010");
		tools.Utils.B_打印List_String(ans);
	}
	static class Solution {
		List<String> ans = new LinkedList<String>();
		HashSet<String> set = new HashSet<>();
		int[] cs = null;
		int[] choice = new int[12];
	    public List<String> restoreIpAddresses(String s) {
	    	if (s == null || s.length() < 4 || s.length() > 12) {
	    		return ans;
	    	}
	    	cs = new int[s.length()];
	    	for (int i = cs.length - 1; i > -1; i --) { 
	    		cs[i] = s.charAt(i) - '0';
	    	}
	    	Arrays.fill(choice, - 1); 
	    	int first_not_zero = 0;
	    	while (true) {
	    		if (first_not_zero > 3 || cs[first_not_zero] != 0) {
	    			break;
	    		} else {
	    			first_not_zero ++;
	    		}
	    	}
	    	if (cs.length == 4) {
		    	if (first_not_zero == 4) {
	    			ans.add("0.0.0.0");
	    			return ans;
		    	} else {
		    		ans.add(String.format("%d.%d.%d.%d", cs[0], cs[1], cs[2], cs[3]));
		    		return ans;
		    	}
    		} else if (first_not_zero == 0) {
		    	choice[0] = cs[0];
		    	choice[11] = cs[cs.length - 1];
		    	search(1, 10, 1, 1, cs.length - 2, 1);
	    	} else {
	    		for (int i = 0; i < first_not_zero * 3; i ++) {
	    			choice[i] = 0;
	    		}
	    		choice[3 * first_not_zero] = cs[first_not_zero];
	    		choice[11] = cs[cs.length - 1];
	    		search(3 * first_not_zero + 1, 10, 3 * first_not_zero + 1, first_not_zero + 1, cs.length - 2, first_not_zero + 1);
	    	}
	        return ans;
	    }
	    // chi,chj : choice的开始和结束index
	    // csi,csj : cs的开始和结束index
	    private void search(int chi, int chj, int chk, int csi, int csj, int csk) {
	    	if (chk > chj || csk > csj) {
	    		isLegal();
	    		return;
	    	}
	    	if (csj - csk > chj - chk) {
	    		return;
	    	}
	    	for (int cht = chk; cht <= chj; cht ++) {
	    		choice[cht] = cs[csk];
	    		search(chi, chj, cht + 1, csi, csj, csk + 1);
	    		choice[cht] = -1;
	    	}
	    }
		// i从0开始
	    boolean isLegal() {
	    	int[] parts = new int[4];
	    	int count = 0;
	    	for (int i = 0; i < parts.length; i ++) {
	    		parts[i] = 0;
		    	int index = i * 3;
		    	boolean isAll_blank = true;
		    	int this_count = 0;
		    	for (int j = 0; j < 3; j ++) {
		    		if (choice[index + j] == -1) {
		    			continue;
		    		}
		    		isAll_blank = false;
		    		this_count ++;
		    		count ++;
		    		if (j != 0 && parts[i] == 0 && choice[index + j] != 0) {
		    			return false;
		    		}
		    		parts[i] = parts[i] * 10 + choice[index + j];
		    	}
		    	if (parts[i] == 0 && this_count != 1) {
		    		count -= (this_count - 1);
		    	}
		    	if (isAll_blank) {
		    		return false;
		    	}
		    	if (parts[i] < 0 || parts[i] > 255) {
		    		return false;
		    	}
	    	}
	    	String temp = String.format("%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
	    	if (count == cs.length  && ! set.contains(temp)) {
		    	ans.add(temp);
		    	set.add(temp);
	    	}
	    	return true;
	    }
	}
	/*
	 * 	AC
	 * 	需要更加简化逻辑,现在的逻辑还是太复杂了.
	 * 	11 ms
	 */
	static class Solution2 {
		List<String> ans = new LinkedList<String>();
		int[] ar = null, ch = null;		// ar是输入的int[]版,ch是选择的12个数字中的一个
		int count = 0, arJ = 0, this_count = 0, del_count = 0;
		HashSet<String> set = new HashSet<>();
		public List<String> restoreIpAddresses(String s) {
			if (s == null || s.length() < 4 || s.length() > 12) {
	    		return ans;
	    	}
			ar = new int[s.length()];
			ch = new int[12];
			arJ = ar.length - 1;
			for (int  i = 0; i < ar.length; i ++) {
				ar[i] = s.charAt(i) - '0';
			}
			Arrays.fill(ch, -1);
			ch[0] = ar[0];
			ch[ch.length - 1] = ar[ar.length - 1];
			int ar_i = 1;
			int ch_min = 1, ch_max = ch.length - 2;
			search(ar_i, ch_min, ch_max);
			return ans;
		}
		// [ar_min, ar_max]  [ch_min, ch_max]
		void search(int ar_i, int ch_min, int ch_max) {
			if (this_count >= ar.length - 2) {
				if (judge()) {
					System.out.printf("第\t%d\t次数据\r\n", del_count ++);
					tools.Utils.printArray(ar, 20);
					tools.Utils.printArray(ch, 20);
				}
				return;
			}
			for (int ch_now = ch_min; ch_now <= ch_max; ch_now ++) {
				ch[ch_now] = ar[ar_i];
				this_count ++;
				search(ar_i + 1, ch_now + 1, ch_max);
				this_count --;
				ch[ch_now] = -1;
			}
		}
		boolean judge() {
			boolean isAllFailue = false;
			StringBuilder st = new StringBuilder(16);
			for (int i = 0; ! isAllFailue && i < 4; i ++) {
				int base = i * 3;
				if (ch[base + 0] == -1 && ch[base + 1] == -1 && ch[base + 2] == -1) {
					isAllFailue = true;
					continue;
				} else if (ch[base + 0] == 0 && (ch[base + 1] != 0 && ch[base + 1] != -1)) {
					isAllFailue = true;
					continue;
				} else if (ch[base + 0] == 0 && ch[base + 1] == 0 && ch[base + 2] != -1) {
					isAllFailue = true;
					continue;
				}
				int value = 0;
				boolean isFirstNot_N_1 = false;
				for (int j = 0; ! isAllFailue && j < 3; j ++) {
					if (ch[base + j] != -1) {
						int temp = value * 10 + ch[base + j];
						if (!isFirstNot_N_1 || (temp != value && value != 0)) {
							value = temp;
						} else {
							isAllFailue = true;
						}
						isFirstNot_N_1 = true;
					}
				}
				if (value < 0 || value > 255) {
					isAllFailue = true;
				}
				st.append(i == 0 ? "" : ".");
				st.append(value);
			}
			if (isAllFailue) {
				return false;
			}
			String now = st.toString();
			if (! set.contains(now)) {
				ans.add(now);
				set.add(now);
				return true;
			}
			return false;
		}
	}
}


C Solution: github

/*
    url: leetcode.com/problems/restore-ip-addresses
    AC 0ms 87.50%
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char* T;
typedef struct al sal;
typedef struct al * pal;

struct al {
    int capacity;
    int size;
    T* arr;
};

pal al_init(int capacity) {
    pal l = (pal) malloc(sizeof(sal));
    if (capacity < 1) return NULL;
    l->arr = (T*) malloc(sizeof(T) * capacity);
    l->capacity = capacity;
    l->size = 0;
    return l;
}

void al_expand_capacity(pal l) {
    T* new_arr = (T*) malloc(sizeof(T) * (l->capacity * 2 + 1));
    int i = 0;
    for (i = 0; i < l->capacity; i ++)
        new_arr[i] = l->arr[i];
    free(l->arr);
    l->arr = new_arr;
    l->capacity = l->capacity * 2 + 1;
}

void al_add_last(pal l, T v) {
    if (l->capacity == l->size) al_expand_capacity(l);
    l->arr[l->size] = v;
    l->size ++;
}

T* al_convert_to_array_free_l(pal l) {
    T* arr = l->arr;
    free(l);
    return arr;
}

void al_print(pal l) {
    int i = 0;
    if (l->size == 0) return;
    printf("================\r\n");
    for (i = 0; i < l->size; i ++)
        printf("%s\r\n", l->arr[i]);
    printf("================\r\n");
    printf("\r\n");
}

char* char_copy(char* r, int rn) {
    char* copy = (char*) malloc(sizeof(char) * rn);
    int i = 0;
    for (i = 0; i < rn-1; i ++)
        copy[i] = r[i];
    copy[rn-1] = '\0';
    return copy;
}

void search(pal l, char* s, int si, int sn, char* r, int ri, int rn, int cnt) {
    int v = 0, i = 0;
    if (si == sn && ri == rn && cnt == 4) {
        al_add_last(l, char_copy(r, rn));
        return ;
    }
    if (si >= sn || ri >= rn || cnt >= 4) return;
    for (i = 0; i < 3 && si+i < sn; i ++) {
        v = v * 10 + s[si + i] - '0';
        if (v > 255) break;
        r[ri+i] = s[si+i];
        r[ri+i+1] = '.';
        search(l, s, si+i+1, sn, r, ri+i+2, rn, cnt+1);
        if (i == 0 && v == 0) break;
    }
} 

char** restoreIpAddresses(char* s, int* rn) {
    pal l = al_init(16);
    int sn = s == NULL ? 0 : strlen(s);
    char* r = NULL;
    if (sn < 4 || sn > 12) return NULL;
    r = (char*) malloc(sizeof(char) * (sn + 4));
    search(l, s, 0, sn, r, 0, sn+4, 0);
    free(r);
    *rn = l->size;
    return al_convert_to_array_free_l(l);
}

int main() {
    /*
        0000            --->  0.0.0.0
        00000           --->  NULL
        25525511135     --->  [255.255.11.135, 255.255.111.35]
        123892398       --->  [123.89.23.98, 123.89.239.8]
        255255255255    --->  [255.255.255.255]
    */
    char* s = "0000";
    int rn = 0;
    char** a = restoreIpAddresses(s, &rn);
    int i = 0;
    for (i = 0; i < rn; i ++) {
        printf("%s\r\n", a[i]);
        free(a[i]);
    }
    free(a);
    return 0;
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/restore-ip-addresses
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年4月23日
    @details:    Solution: 48ms 85.48%
'''

class Solution(object):
    def search(self, v, vi, vn, r, ri, rn, a):
        if vi == vn and ri == rn:
            a.append('%d.%d.%d.%d'%tuple(r))
        if vi >= vn or ri >= rn: return
        s = 0
        for i in range(3):
            if i+vi >= vn: break
            s = s*10 + v[vi+i]
            if i != 0 and s < 10: break
            if s > 255: break
            r[ri] = s
            self.search(v, vi+i+1, vn, r, ri+1, rn, a)
        
    def restoreIpAddresses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        sn = 0 if s == None else len(s)
        v = [int(s[i]) for i in range(sn)]
        r, a = [0]*4, []
        self.search(v, 0, sn, r, 0, 4, a)
        return a
    
if __name__ == "__main__":
    m = [
            "0000",
            "000",
            "00000",
            "1111",
            "9999",
            "255255255255",
            "19216813130",
            "010010",
        ]
    for s in m:
        print(s)
        print(Solution().restoreIpAddresses(s))
        print("============")
        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值