今天因为某个原因,没学习
但是
晚上做了一个算法题,可能会笑人,一晚上做一个题,我说,没错,从19点多到现在22.18,一晚上,只做出来了一道题。
这是我做的真正意义上的第一道算法题,并且实现了的
今天就写这道题吧
先上题目
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
示例 1:
输入:words = [“cat”,“bt”,“hat”,“tree”], chars = “atach”
输出:6
解释:
可以形成字符串 “cat” 和 “hat”,所以答案是 3 + 3 = 6。
示例 2:
输入:words = [“hello”,“world”,“leetcode”], chars = “welldonehoneyr”
输出:10
解释:
可以形成字符串 “hello” 和 “world”,所以答案是 5 + 5 = 10。
提示:
1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100
所有字符串中都仅包含小写英文字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的思路就是将words中的每个String拿出来转换成char的集合,然后再将chars转换成char的集合,进行一一比较
但是遇见第一个问题
1、匹配次数总多于预期值
我是按照给的第一个例子做的,因为忽略了不能重复使用chars的限定条件,所以将bt、tree中的t也计算上了
解决方法:在循环体里面将chars重构,目的是去除掉已经用过的字符
chars = chars.substring(0, chars.indexOf(String.valueOf(a[j]))) + chars.substring(chars.indexOf(String.valueOf(a[j])) + 1);
并在words查找完当前的字符串后,恢复chars的初始值
这样还是有缺陷的,计算时间和内存上大大增加
2、提交通过了但是时间和内存消耗过大
直接上最终代码
public static void main(String[] args) {
int count = 0;//计数器
int sum = 0;//最终总和
String[] words = new String[]{"dyiclysmffuhibgfvapygkorkqllqlvokosagyelotobicwcmebnpznjbirzrzsrtzjxhsfpiwyfhzyonmuabtlwin", "ndqeyhhcquplmznwslewjzuyfgklssvkqxmqjpwhrshycmvrb", "ulrrbpspyudncdlbkxkrqpivfftrggemkpyjl", "boygirdlggnh", "xmqohbyqwagkjzpyawsydmdaattthmuvjbzwpyopyafphx", "nulvimegcsiwvhwuiyednoxpugfeimnnyeoczuzxgxbqjvegcxeqnjbwnbvowastqhojepisusvsidhqmszbrnynkyop", "hiefuovybkpgzygprmndrkyspoiyapdwkxebgsmodhzpx", "juldqdzeskpffaoqcyyxiqqowsalqumddcufhouhrskozhlmobiwzxnhdkidr", "lnnvsdcrvzfmrvurucrzlfyigcycffpiuoo", "oxgaskztzroxuntiwlfyufddl", "tfspedteabxatkaypitjfkhkkigdwdkctqbczcugripkgcyfezpuklfqfcsccboarbfbjfrkxp", "qnagrpfzlyrouolqquytwnwnsqnmuzphne", "eeilfdaookieawrrbvtnqfzcricvhpiv", "sisvsjzyrbdsjcwwygdnxcjhzhsxhpceqz", "yhouqhjevqxtecomahbwoptzlkyvjexhzcbccusbjjdgcfzlkoqwiwue", "hwxxighzvceaplsycajkhynkhzkwkouszwaiuzqcleyflqrxgjsvlegvupzqijbornbfwpefhxekgpuvgiyeudhncv", "cpwcjwgbcquirnsazumgjjcltitmeyfaudbnbqhflvecjsupjmgwfbjo", "teyygdmmyadppuopvqdodaczob", "qaeowuwqsqffvibrtxnjnzvzuuonrkwpysyxvkijemmpdmtnqxwekbpfzs", "qqxpxpmemkldghbmbyxpkwgkaykaerhmwwjonrhcsubchs"};
String chars = "usdruypficfbpfbivlrhutcgvyjenlxzeovdyjtgvvfdjzcmikjraspdfp";
final String preChar = chars;//先保存好初始值,final是为了减少内存
for (int i = 0; i < words.length; i++) {//循环遍历words
char[] a = words[i].toCharArray();//将当下的words中的字符串转换成字符集合
for (int j = 0; j < a.length; j++) {//
if (chars.contains(String.valueOf(a[j]))) {//如果chars字符串中存在a的当下的字符
chars = chars.substring(0, chars.indexOf(String.valueOf(a[j]))) + chars.substring(chars.indexOf(String.valueOf(a[j])) + 1);
count++;//上一行代码重构了chars,当下这行是计数器加一
} else {
break;//优化
}
if (count == a.length) {//若计数器与words当下的字符串的长度相等
sum += count;//计入总数
break;//优化
}
}
count = 0;//重置计数器
chars = preChar;//恢复chars
}
System.out.println(sum);
这次测验的是非常长的字符数组words和字符串chars
解释都在注释里面了
这是几次测试的结果,真难,算法真难,也挺有意思
正因为有了音乐,才有了相遇的瞬间,有了相会的感动,有了相逢的人们,有了邂逅的思念。
——四月是你的谎言