【华为OD题库-074】VLAN资源池-Java

题目

VLAN是一种对局域网设备进行逻辑划分的技术,为了标识不同的VLAN,引入VLAN ID(1-4094之间的整数)的概念。定义一个VLAN ID的资源池(下称VLAN资源池),资源池中连续的VLAN用开始VLAN-结束VLAN表示,不连续的用单个整数表示,所有的VLAN用英文逗号连接起来。
现在有一个VLAN资源池,业务需要从资源池中申请一个VLAN,需要你输出从VLAN资源池中移除申请的VLAN后的资源池。
输入描述:
第一行为字符串格式的VLAN资源池,
第二行为业务要申请的VLAN,VLAN的取值范围为[1,4094]之间的整数。
输出描述:
从输入VLAN资源池中移除申请的VLAN后字符串格式的VLAN资源池,输出要求满足题目描述中的格式,并且按照VLAN从小到大升序输出。
如果申请的VLAN不在原VLAN资源池内,输出原VLAN资源池升序排序后的字符串即可。
示例1:
输入
1-5
2
输出
1,3-5
说明
原VLAN资源池中有VLAN1、2、3、4、5,从资源池中移除2后,剩下VLAN1、3、4、5,按照题目描述格式并升序后的结果为1,3-5。
示例2:
输入
20-21,15,18,30,5-10
15
输出
5-10,18,20-21,30
说明
原VLAN资源池中有VLAN5、6、7、8、9、10、15、18、20、21、30,从资源池中移除15后,资源池中剩下的VLAN为5、6.7、8、9、10、18、20、21、30,按照题目描述格式并升序后的结果为5-10,18,20-21,30。
示例3:
输入
5,1-3
10
输出
1-3,5
说明
原VLAN资源池中有VLAN1、2、3,5,申请的VLAN 10不在原资源池中,将原资源池按照题目描述格式并按升序排序后输出的结果为1-3,5。
备注:
输入VLAN资源池中VLAN的数量取值范围为[2-4094]间的整数,资源池中VLAN不重复且合法([1,4094]之间的整数),输入是乱序的。

思路

先将输入转为自定义对象VLAN集合list,包含两个属性start和end,不连续的单个整数其start和end相等
将list排序,VLAN实现Comparable接口,从而实现自定义排序:按照start值的升序排序(题目输入数据无重复,所以start不可能相等)
需要找到目标target(业务申请的VLAN编号)在排序后的list中的索引位置idx(start<=target<=end即可)
list中移出idx的元素,并考虑是否会产生新的区间:

  1. 如果匹配的区间是单个整数,直接移出即可
  2. 否则,产生两个新的区间:[target+1,end],[start,target-1],将新区间加入到list中,需对list重新排序

遍历list,按照格式组装结果即可。如果是单个则输出单个,否则输出start-end的形式。可通过重写VLAN的toString方法实现

题解

package hwod;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class VlanPool {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int target = sc.nextInt();
        System.out.println(vlanPool(str, target));
    }

    private static String vlanPool(String str, int target) {
        List<Vlan> list = new ArrayList<>();
        String[] split = str.split(",");
        for (int i = 0; i < split.length; i++) {
            if (split[i].contains("-")) {
                String[] range = split[i].split("-");
                list.add(new Vlan(Integer.parseInt(range[0]), Integer.parseInt(range[1])));
            } else {
                list.add(new Vlan(Integer.parseInt(split[i]), Integer.parseInt(split[i])));
            }
        }
        Collections.sort(list);
        int idx = -1;//target在list的哪个位置
        for (int i = 0; i < list.size(); i++) {
            Vlan cur = list.get(i);
            if (target >= cur.getStart() && target <= cur.getEnd()) {
                idx = i;
                break;
            }
        }
        if (idx != -1) {
            //移出目标
            Vlan cur = list.get(idx);
            list.remove(idx);
            if (target > cur.getStart()) {
                Vlan range1 = new Vlan(cur.getStart(), target - 1);
                list.add(range1);
            }
            if (target < cur.getEnd()) {
                Vlan range2 = new Vlan(target + 1, cur.getEnd());
                list.add(range2);
            }
            Collections.sort(list);
        }


        //返回结果
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i != 0) sb.append(",");
            sb.append(list.get(i));
        }
        return sb.toString();

    }
}

class Vlan implements Comparable<Vlan> {
    private int start;
    private int end;

    public Vlan(int start, int end) {
        this.start = start;
        this.end = end;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
    @Override
    public int compareTo(Vlan o) {
        return this.start - o.start;
    }

    @Override
    public String toString() {
        if (start == end) return String.valueOf(start);
        return start + "-" + end;
    }
}

上述实现是先将内容加入了list,再找到目标位置,移除后再排序。实际可以直接在加入时判断其是否为目标范围,优化如下:

package hwod;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class VlanPool {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int target = sc.nextInt();
        System.out.println(vlanPool(str, target));
    }

    private static String vlanPool(String str, int target) {
        List<Vlan> list = new ArrayList<>();
        String[] split = str.split(",");
        for (int i = 0; i < split.length; i++) {
            Vlan vlan = null;
            if (split[i].contains("-")) {
                String[] range = split[i].split("-");
                vlan = new Vlan(Integer.parseInt(range[0]), Integer.parseInt(range[1]));
            } else {
                vlan = new Vlan(Integer.parseInt(split[i]), Integer.parseInt(split[i]));
            }
            if (target >= vlan.getStart() && target <= vlan.getEnd()) {
                if (target > vlan.getStart()) {
                    list.add(new Vlan(vlan.getStart(), target - 1));
                }
                if (target < vlan.getEnd()) {
                    list.add(new Vlan(target + 1, vlan.getEnd()));
                }
            } else {
                list.add(vlan);
            }

        }
        Collections.sort(list);

        //返回结果
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i != 0) sb.append(",");
            sb.append(list.get(i));
        }
        return sb.toString();

    }
}

class Vlan implements Comparable<Vlan> {
    private int start;
    private int end;

    public Vlan(int start, int end) {
        this.start = start;
        this.end = end;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    @Override
    public int compareTo(Vlan o) {
        return this.start - o.start;
    }

    @Override
    public String toString() {
        if (start == end) return String.valueOf(start);
        return start + "-" + end;
    }
}

推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

你可能感兴趣的:(华为OD题库JAVA题解,华为od,java)