【快手面试】网站用户名调整为符合规则最小操作次数

网站用户名,规则如下:
1. 同时包含大写字母、小写字母、数字
2. 长度12-20

给定任意字符串(简单起见,不包含其他特殊字符),可以对其进行增加、删除、替换操作,每次只能操作一个字符。问,最少经过多少次操作,能使其满足前面提到的网站用户名的要求

例如:
aaabbbccc -> 3
aaabbbcccdddeeefffggg -> 3

代码如下

import java.util.ArrayList;
import java.util.List;

public class WebsiteNameCheck {
    public static void main(String[] args) {
        WebsiteNameCheck cha = new WebsiteNameCheck();
        cha.checkName("sd");
        cha.checkName("sd1");
        cha.checkName("sd1U");
        cha.checkName("sdfjsdaaaa");
        cha.checkName("1111111111");
        cha.checkName("AAAAAAAAAAAA");
        cha.checkName("AAAAAAAAAAAA112334DDDddddd");
        cha.checkName("sdfjsd123");
        cha.checkName("sdfUd123");
    }

    private static int MIN_LENGTH = 6;
    private static int MAX_LENGTH = 12;

    public void checkName(String src) {
        //大写字母位置记录
        List<Integer> upper = new ArrayList<>();
        //小写字母位置记录
        List<Integer> lower = new ArrayList<>();
        //数字位置记录
        List<Integer> num = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < src.length(); i++) {
            char ch = src.charAt(i);
            sb.append(ch);
            if (ch >= 'A' && ch <= 'Z') {
                upper.add(i);
            } else if (ch >= 'a' && ch <= 'z') {
                lower.add(i);
            } else {
                num.add(i);
            }
        }

        int index = this.adjust(sb, upper, lower, num);
        System.out.println("src:" + src + " to desc:" + sb.toString() + " adjest:" + index);
    }

    public int adjust(StringBuilder sb, List<Integer> upper,
                      List<Integer> lower,
                      List<Integer> num) {

        int index = 0;
        // 长度不足时进行数据填充
        if (sb.length() < MIN_LENGTH) {
            if (sb.length() < MIN_LENGTH && upper.size() == 0) {
                sb.append("U");
                upper.add(sb.length() - 1);
                index++;
            }
            if (sb.length() < MIN_LENGTH && lower.size() == 0) {
                sb.append("u");
                lower.add(sb.length() - 1);
                index++;
            }
            if (sb.length() < MIN_LENGTH && num.size() == 0) {
                sb.append("0");
                num.add(sb.length() - 1);
                index++;
            }
            // 后面即可随机填充,这里默认填充0
            while (sb.length() < MIN_LENGTH) {
                sb.append(0);
                index++;
            }
        }
        return index + this.adjustChar(sb, upper, lower, num);

    }

    /**
     * 删除超长的字符
     *
     * @param sb    带操作的字符集合
     * @param index 变化的次数
     * @param more  删除的字符串索引
     * @return
     */
    private int removeExtraChar(StringBuilder sb, int index, List<Integer> more) {
        for (int i = more.size(); i > 1 && sb.length() > MAX_LENGTH; i--) {
            int j = more.get(i - 1);
            sb.delete(j, j + 1);
            index++;
        }
        return index;
    }

    private int adjustChar(StringBuilder sb, List<Integer> upper,
                           List<Integer> lower,
                           List<Integer> num) {
        // 调整策略,找到最长的种类作为调整依据
        List<Integer> replace = new ArrayList<>();
        if (replace.size() < upper.size()) {
            replace = upper;
        }
        if (replace.size() < lower.size()) {
            replace = lower;

        }
        if (replace.size() < num.size()) {
            replace = num;
        }
        int index = 0;
        if (upper.size() == 0) {
            sb.replace(replace.get(0), replace.get(0) + 1, "U");
            upper.add(replace.get(0));
            replace.remove(0);
            index++;
        }
        if (lower.size() == 0) {
            sb.replace(replace.get(0), replace.get(0) + 1, "u");
            lower.add(replace.get(0));
            replace.remove(0);
            index++;
        }
        if (num.size() == 0) {
            sb.replace(replace.get(0), replace.get(0) + 1, "0");
            num.add(replace.get(0));
            replace.remove(0);
            index++;
        }
        if (replace.size() > MAX_LENGTH) {
            replace = mergeTwoSortList(upper.subList(1, upper.size()), num.subList(1, num.size()));
            replace = mergeTwoSortList(replace, lower.subList(1, lower.size()));
            index = removeExtraChar(sb, index, replace);
        }
        return index;
    }

    public List<Integer> mergeTwoSortList(List<Integer> aList, List<Integer> bList) {
        int aLength = aList.size(), bLength = bList.size();
        List<Integer> mergeList = new ArrayList<Integer>();
        int i = 0, j = 0;
        while (aLength > i && bLength > j) {
            if (aList.get(i) > bList.get(j)) {
                mergeList.add(i + j, bList.get(j));
                j++;
            } else {
                mergeList.add(i + j, aList.get(i));
                i++;
            }
        }
        // blist元素已排好序, alist还有剩余元素
        while (aLength > i) {
            mergeList.add(i + j, aList.get(i));
            i++;
        }
        // alist元素已排好序, blist还有剩余元素
        while (bLength > j) {
            mergeList.add(i + j, bList.get(j));
            j++;
        }
        return mergeList;

    }
}

运行结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值