LeetCode——748.最短补全词

通过万岁!!!

  • 题目:给你一个字符串S,由大小写字母和空格组成,然后给你一个字符串数组(这里面的字符串只有小写字母)。在字符串数组中找到一个字符串,能够将S中的所有字母(S中不区分大小写)都用完,可以不够,但是必须全都用完。如果有多个结果,则返回最短的哪个,如果还有多个最短的,就返回下标最小的。
  • 思路:首先记录S都有那些字符,这里用一个长度为26的数组就可以了。因为后面我们不区分大小写,而且只看字母。然后遍历每个字符串,每次用一个就–,然后看看这个数组中还有没有大于0的数。如果有的话就说明S的字符没有完全用完。这是第一步的结果,但是还要求什么最短和下标小等。最终才得到最终结果。
  • 技巧:
    • 这里需要注意的是,我们记录S中字符个数的字符串,是需要还原的。我才用的方式是Copy一份。当然可以再遍历。
    • 然后就是满足结果(能够把)的字符串需要记录。然后遍历找到长度最小的。这里记录的时候建议采用LinkedList。如果满足第一步的情况特别多的话,LinkedList应该会好点。
      • 这里可以升级,我们可以直接在找到这个满足第一步结果的时候,记录要返回的下标,而下标的更新只有长度比已知最终的结果的小的时候才更新。

伪代码

定义一个LinkedList,用来记录所有满足第一步结果的字符串
定义长度为26的数组lic,用来记录每次字符出现的字数
for统计字符串中字符出现的次数
拷贝数组lic,得到licCopy
for遍历字符串数组
    for遍历字符串数组中第i个字符串的字符
        在licCopy中进行--
    遍历licCopy数组,
        查看是不是还有大于0的,如果有说明没有全部用完,第一步结果都不满足,重新还原licCopy数组,然后break;
        如果是遍历到licCopy数组的最后一个,那么说明现在这个字符串是满足条件的,添加到LinkedList中,这里也要重新还原licCopy数组
遍历LinkedList,找到长度最小的,注意这里不用考虑下标,因为如果长度相等,不进行替换即可。
return 找到的字符串

java代码

class Solution {
    public String shortestCompletingWord(String licensePlate, String[] words) {
        LinkedList<String> ansList = new LinkedList();
        int lic[] = new int[26];
        int tempC = ' ';
        for (int i = 0; i < licensePlate.length(); i++) {
            tempC = licensePlate.charAt(i);
            if (tempC > 64 && tempC < 91)
                lic[tempC - 65]++;
            if (tempC > 96 && tempC < 123)
                lic[tempC - 97]++;
        }
        int[] licCopy = Arrays.copyOf(lic, 26);
        for (int i = 0; i < words.length; i++) {
            for (int j = 0; j < words[i].length(); j++) {
                tempC = words[i].charAt(j);
                if (tempC > 96 && tempC < 123)
                    licCopy[tempC - 97]--;
            }
            for (int j = 0; j < 26; j++) {
                if (licCopy[j] > 0) {// 只要有大于0的,就返回
                    licCopy = Arrays.copyOf(lic, 26);
                    break;
                }
                if (j == 25) {// 最后一个并且没有返回
                    ansList.addLast(words[i]);
                    licCopy = Arrays.copyOf(lic, 26);
                }
            }
        }
        tempC = Integer.MAX_VALUE;
        for (String s : ansList) {
            if (tempC > s.length()) {
                tempC = s.length();
                words[0] = s;
            }
        }
        return words[0];
    }
}

伪代码——升级,主要是上面还需要再遍历LinkedList,其实我们可以再上面的双重for中直接得到想要的结果,这样就不用

LinkedList,并且少一次for
定义一个需要返回的字符串在字符串数组中的下标的变量,ansIdx
定义长度为26的数组lic,用来记录每次字符出现的字数
定义长度为26的数组licCopy
for统计字符串中字符出现的次数
for遍历字符串数组
    for遍历字符串数组中第i个字符串的字符
        在licCopy中进行--
    遍历licCopy数组,
        查看是不是还有大于0的,如果有说明没有全部用完,第一步结果都不满足,重新还原licCopy数组,然后break;
        如果是遍历到licCopy数组的最后一个,那么说明现在这个字符串是满足条件的,但是需要判断这个字符串的长度是不是比已知的长度小,如果小才重新将新的下标赋值给ansIdx。并且也需要重新还原licCopy数组。
return 字符串数组[ansIdx];

java代码——升级

class Solution {
    public String shortestCompletingWord(String licensePlate, String[] words) {
        int ansIdx = -1;
        int lic[] = new int[26];
        int licCopy[] = new int[26];
        int tempC = ' ';
        for (int i = 0; i < licensePlate.length(); i++) {
            tempC = licensePlate.charAt(i);
            if (tempC > 64 && tempC < 91)
                lic[tempC - 65]++;
            if (tempC > 96 && tempC < 123)
                lic[tempC - 97]++;
        }
        System.arraycopy(lic, 0, licCopy, 0, 26);
        for (int i = 0; i < words.length; i++) {
            for (int j = 0; j < words[i].length(); j++) {
                tempC = words[i].charAt(j);
                if (tempC > 96 && tempC < 123)
                    licCopy[tempC - 97]--;
            }
            for (int j = 0; j < 26; j++) {
                if (licCopy[j] > 0) {// 只要有大于0的,就返回
                    System.arraycopy(lic, 0, licCopy, 0, 26);
                    break;
                }
                if (j == 25) {// 最后一个并且没有返回
                    System.arraycopy(lic, 0, licCopy, 0, 26);
                    if (ansIdx == -1) {
                        ansIdx = i;
                        break;
                    }
                    if (words[ansIdx].length() > words[i].length())
                        ansIdx = i;
                }
            }
        }
        return words[ansIdx];
    }
}
  • 总结:题目不难,就是转变成便利字符即可。注意数组的拷贝后来使用System.arraycopy是因为他的效率比较高。做算法题需要循序渐进,先通过,然后再看看可不可以优化,如果直接想优化的方式,还是比较困难的。优化的方式可以慢慢思索,题目做多了也就有经验了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值