面试经典150题0426

面试经典150题0426

Leetcode068 文本左右对齐

贪心:每一行尽量放更多的单词。对于最后一行要特殊处理。对于一行只有一个单词的,将单词左对齐。对于其他普通情况,需要计算空格能否平均分配到间隙中,如果不能,向下取整,然后将多余的空格从左到右分配到每个间隙中。

public static List<String> fullJustify(String[] words, int maxWidth){
    List<String> ans = new ArrayList<>();
    int n = words.length;
    List<String> list = new ArrayList<>();
    for (int i = 0; i < n;) {
        // 移除列表中的所有元素
        list.clear();
        list.add(words[i]);
        // 记录当前单词的长度
        int currLen = words[i++].length();
        // 填充maxWidth的最大单词数量
        // +1为每个单词后最少跟随一个空格
        while (i < n && currLen + 1 + words[i].length() <= maxWidth){
            // 没满,继续尝试填充
            currLen += 1 + words[i].length();
            list.add(words[i++]);
        }

        // 最后一行处理为左对齐
        if(i == n){
            StringBuilder sb = new StringBuilder(list.get(0));
            for (int j = 1; j < list.size(); j++) {
                sb.append(" ").append(list.get(j));
            }
            // 不满,将空格填充到最后
            while (sb.length() < maxWidth){
                sb.append(" ");
            }
            ans.add(sb.toString());
            break;
        }

        int cnt = list.size();

        // 当前行只有一个单词,特殊处理为左对齐
        if(cnt == 1){
            StringBuilder sb = new StringBuilder(list.get(0));
            while (sb.length() != maxWidth){
                sb.append(" ");
            }
            ans.add(sb.toString());
            continue;
        }

        // 其余情况
        // 当前行单词总长度 = 总长度 - 空格数量
        int wordWidth = currLen - (cnt - 1);
        // 需要填充的空格数量
        int spaceWidth = maxWidth - wordWidth;
        // 单词中间需要填充的空格数量,需要向下取整
        int spaceItemWidth = spaceWidth / (cnt - 1);
        StringBuilder spaceItem = new StringBuilder();
        for (int j = 0; j < spaceItemWidth; j++) {
            spaceItem.append(" ");
        }
        StringBuilder sb = new StringBuilder();
        for(int k = 0, sum = 0; k < cnt; k++){
            sb.append(list.get(k));
            if(k == cnt - 1){
                break;
            }
            sb.append(spaceItem);
            sum += spaceItemWidth;
            // 剩余单词间的间隙数量
            // cnt - k - 1为处理到第k个单词剩余间隙数量,再减1代表当前单词后面的间隙已经处理
            int remain = cnt - k - 1 - 1;
            if(remain * spaceItemWidth + sum < spaceWidth){
                // 将不能平均分配到所有间隙的空格数量,尽量安排到靠左的间隙中
                sb.append(" ");
                sum++;
            }
        }
        ans.add(sb.toString());
    }
    return ans;
}
Leetcode125 验证回文串

双指针:先将字符串中大写字母转为小写字母,然后左指针和右指针分别扫描字符,扫描到字母或者数字则进行判断,否则继续移动指针。

public static boolean isPalindrome(String s){
    int left = 0, right = s.length() - 1;
    String str = s.toLowerCase();
    while (left < right){
        while (left < right && !Character.isLetter(str.charAt(left)) && !Character.isDigit(str.charAt(left))){
            left++;
        }
        while (left < right && !Character.isLetter(str.charAt(right)) && !Character.isDigit(str.charAt(right))){
            right--;
        }
        if(str.charAt(left) != str.charAt(right)){
            return false;
        }
        left++;
        right--;
    }
    return true;
}

s.toLowerCase():将字符串中大写字母转换为小写字母。

Character.isLetter():判断字符是否为字母。

Character.isDigit():判断字符是否为数字。

Leetcode392 判断子序列

双指针:两个指针分别指向字符串s和字符串t,字符相等两个指针同时移动,不相等只移动s的指针。

public static boolean isSubsequence(String s, String t){
    int sPtr = 0, tPtr = 0;
    while (sPtr < s.length() && tPtr < t.length()){
        if(s.charAt(sPtr) == t.charAt(tPtr)) {
            sPtr++;
            tPtr++;
            continue;
        }
        tPtr++;
    }
    return sPtr == s.length();
}
Leetcode167 两数之和Ⅱ 输入有序数组

双指针,分别指向数组两端。当指针所指两数之和小于target,左指针向右移动;大于target时右指针向左移动。

public static int[] twoSum(int[] numbers, int target){
    int left = 0, right = numbers.length - 1;
    while (left < right){
        int tmp = numbers[left] + numbers[right];
        if(tmp == target){
            return new int[]{left+1, right+1};
        }
        else if(tmp < target){
            left++;
        }
        else {
            right--;
        }
    }
    return new int[]{-1, -1};
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值