字节跳动面试算法题——还原IP地址

11 篇文章 0 订阅

在这里插入图片描述

题目

给定一个只包含数字的字符串,用以表示一个IP(IPV4)地址,返回所有的有效IP 地址

  • IPV4
  • 192.168.111.111有效
  • 192.168.111.011和192.168.111.256无效
  • 例如:
    • 输入:19216811122
    • 输出:192.168.11.122, 192.168.111.22

分析

  • IPV4共4段,每段数值在[0,255]区间内,使用"."分割
  • 每段数值的位数在[1,3]区间内,计算每段数值的位数的排列
    • 19216811122共有11位数字,划分为4段,每段数值的位数的排列:[2, 3, 3, 3], [3, 2, 3, 3], [3, 3, 2, 3], [3, 3, 3, 2]
    • 对应的IP:[19.216.811.122], [192.16.811.122], [192.168.11.122],
      [192.168.111.22]
  • 排除掉数值>255的IP地址
    • 因811 > 255,排除掉[19.216.811.122], [192.16.811.122]
    • 剩下[192.168.11.122], [192.168.111.22]
      在这里插入图片描述

题解

采用回溯算法来实现

public class IpAddresses {
  // IPV4共分4段
  int group = 4;

  /**
   * 还原IP
   *
   * @param s
   * @return
   */
  public List<String> restore(String s) {
    List<List<Integer>> permList = new ArrayList<>();
    // 计算每段数值的位数的排列
    permutation(permList, new ArrayList<>(), s.length());
    List<String> res = new ArrayList<>();
    // 按照计算出来的排列还原IP
    handleIP(s, permList, res);
    return res;
  }

  /**
   * 根据数值的位数的排列,还原IP
   *
   * @param s
   * @param permList
   * @param res
   */
  private void handleIP(String s, List<List<Integer>> permList, List<String> res) {
    for (List<Integer> list : permList) {
      int index = 0;
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < list.size(); i++) {
        String sTmp = s.substring(index, index += list.get(i));
        // 排除数值以"0"开头的无效IP
        if (sTmp.length() > 1 && sTmp.startsWith("0")) break;
        // 排除数值>255的无效IP
        if (Integer.valueOf(sTmp) > 255) break;
        sb.append(Integer.valueOf(sTmp));
        if (i < list.size() - 1) sb.append(".");
        else res.add(sb.toString());
      }
    }
  }

  /**
   * "回溯",计算数值的位数的排列
   *
   * @param res
   * @param list
   * @param length
   */
  private void permutation(List<List<Integer>> res, List<Integer> list, int length) {
    if (list.size() > group || length < 0) return;
    if (list.size() == group && length == 0) {
      res.add(new ArrayList<>(list));
      return;
    }
    for (int i = 1; i < group; i++) {
      list.add(i);
      permutation(res, list, length - i);
      list.remove(list.size() - 1);
    }
  }

  public static void main(String[] args) {
    IpAddresses ipAddresses = new IpAddresses();
    String s = "19216811122";
    System.out.println(ipAddresses.restore(s));
  }
}

总结

本题被包装成一个还原IP的问题,经分析可转化为求解4个数字的排列问题。找到了问题的本质,往往就找到了解题的思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡矣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值