【11.30】
【第一题】旋转数字
分析:2、5、6、9这些数都可以旋转180度,并且旋转之后的数字不是它本身。
有效数字:0、1、2、5、6、8、9
无效数字:3、4、7
万能数字:2、5、6、9
有效数字-万能数字=搭配数字:0、1、8
情况如下:
1)含有无效数字,则不是好数;
2)只含有万能数字,则一定是好数;
3)万能数字+搭配数字的组合,则一定是好数。
总结: 第一点:不能含有无效数字; 第二点:至少含有一个万能数字。
方法一:消消乐替换。用字符串替换的方法会很慢,但是简洁容易理解;另外也可以用contains()方法来判断存不存在;
方法二:动态规划。
//方法一:消消乐替换
//执行用时:22 ms, 在所有 Java 提交中击败了17.85% 的用户
//内存消耗:37.8 MB, 在所有 Java 提交中击败了35.51% 的用户
class Solution {
public int rotatedDigits(int N) {
int count = 0;
for(int i = 0;i <= N;i++){
if(isGood(i)){
count++;
}
}
return count;
}
boolean isGood(int n){
String t = Integer.toString(n);
String s = t.replace("3","").replace("4","").replace("7","");
if(s.length() < t.length()){
return false;
}
else{
s = t.replace("2","").replace("5","").replace("6","").replace("9","");
if(s.length() < t.length()){
return true;
}
else{
return false;
}
}
}
}
【第二题】数组中的字符串匹配
分析:可以先将字符串数组中的字符串按照长度从小到大排序,然后设置两个指针,i在前j在后,判断i指向的字符是否包含在j里即可。
Q1:这么一个“包含”的判断要如何实现?
A1:java方法——contains()或indexOf();
A2:哈希表。
A3:暴力法滑动窗口。
//执行用时:3 ms, 在所有 Java 提交中击败了95.09% 的用户
//内存消耗:38.7 MB, 在所有 Java 提交中击败了64.65% 的用户
class Solution {
public List<String> stringMatching(String[] words) {
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
};
List<String> list =new ArrayList<>();
Arrays.sort(words,comparator);
for (int i = 0; i < words.length - 1; i++) {
for (int j = i + 1; j < words.length ; j++) {
if(words[j].indexOf(words[i]) != -1) {
list.add(words[i]);
break;
}
}
}
return list;
}
}
【第三题】外观数列
分析:countAndSay(n)是对countAndSay(n-1)的描述;首先遍历第n-1个字符串,相同的字符i统计数量x,然后形成新字符串(x连接x个i)。
方法:设置两个指针i,j,用来统计重复元素的数量(j-i+1),以及重复的元素pre.charAt(i)。
//执行用时:10 ms, 在所有 Java 提交中击败了26.44% 的用户
//内存消耗:37.9 MB, 在所有 Java 提交中击败了26.80% 的用户
class Solution{
public String countAndSay(int n){
StringBuffer pre = new StringBuffer("1");
StringBuffer cur = new StringBuffer("1");
for(int i = 1;i < n;i++){
pre = cur;
cur = new StringBuffer();
int start = 0,end = 0;
while(end < pre.length()){
while(end < pre.length() && pre.charAt(start) == pre.charAt(end)){
end++;
}
cur = cur.append(Integer.toString(end-start)).append(pre.charAt(start));
start = end;
}
}
return cur.toString();
}
}
【第四题】唯一摩尔斯密码词
分析:
方法一:普通数组。首先可以将字符串数组中的字符串全部先翻译成摩尔斯密码,存入数组,然后遍历数组,用每个字符串试探contains,假如存在,遍历下一个,不存在的话,计数器+1;
方法二:哈希表。将数组word中每个单词转换为摩尔斯码,并加入哈希集合中,最终的答案即为哈希集合中元素的个数。
(因为集合不存在重复的元素)
方法三:二叉树。编码只有"-“和”."两种,所有可以用二叉树来存储编码,最后叶子节点的数量就是所求答案。想法满新颖的,但是运行速度有点慢。
//步骤:
//1.将每个单词的摩尔斯码存入MORSE数组;
//2.遍历单词数组的每个单词,并进行如下操作
//2.1 将每个单词都建立一个StringBuilder;
//2.2 将单词转换为字符数组;
//2.3 遍历字符数组