LeetCode中的集合和映射相关的问题
804.唯一的摩斯密码词
国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a"
对应 ".-"
, "b"
对应 "-..."
, "c"
对应 "-.-."
, 等等。
为了方便,所有26个英文字母对应摩尔斯密码表如下:
[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-.-....-",(即 "-.-." + "-..." + ".-"字符串的结合)。我们将这样一个连接过程称作单词翻译。
返回我们可以获得所有词不同单词翻译的数量。
例如:
输入: words = ["gin", "zen", "gig", "msg"]
输出: 2
解释:
各单词翻译如下:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."
共有 2 种不同翻译, "--...-." 和 "--...--.".
注意:
- 单词列表
words
的长度不会超过100
。 - 每个单词
words[i]
的长度范围为[1, 12]
。 - 每个单词
words[i]
只包含小写字母。
思路:
将摩斯密码转换表用字符串数组存起来
然后遍历输入的字符串组,拿到当前字符串(chatAt())的索引(根据索引才能利用转化表)将其转换为摩斯密码并拼接到res中,
并用一个集合数据结构(TreeSet)来保存add(res.toString())进去实现去重功能
最后返回这个集合的元素个数即可
public class Solution {
public static int uniqueMorseRepresentations(String[] words) {
String[] codes = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...",
"-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
/**
* TreeSet基于红黑树实现的集合
*/
//新建TreeSet一个对象
TreeSet<String> set = new TreeSet<>();
//遍历word数组
for (String word : words) {
StringBuilder res = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
word.charAt(i);//获得当前字符
//获得在code是的索引,将转换的Morse码拼接到res中
res.append(codes[word.charAt(i) - 'a']);//a-a=0,b-a=1
}
set.add(res.toString());//将res里面的字符串添加到set中,set会自动帮我们去重
System.out.println(res.toString());
}
return set.size();
}
测试:
public static void main(String[] args) {
String[] words = {"gin", "zen", "gig", "msg"};
System.out.println("字符串中的莫斯密码有:" + uniqueMorseRepresentations(words) + "种");
}
结果:
--...-.
--...-.
--...--.
--...--.
字符串中的莫斯密码有:2两种
349. 两个数组的交集
给定两个数组,写一个函数来计算它们的交集。
例子:
给定 num1= [1, 2, 2, 1]
, nums2 = [2, 2]
, 返回 [2]
.
提示:
- 每个在结果中的元素必定是唯一的。
- 我们可以不考虑输出结果的顺序。
解题思路:
交集:输出的那一个数一定是唯一,所以可以用集合Set来去重
首先,将数组num1遍历后放到集合(TreeSet)中,实现了对数组1去重
其次,将数组num2遍历后,看集合(TreeSet)是否包含有该元素,有的话(准备一个数组List),将元素存起来,并在集合中删除这个元素
最后,新建一个数组arr(长度是的List的长度),将arr打印输出即可
public class Solution1 {
public static int[] intersection(int[] num1, int[] num2) {
TreeSet<Integer> treeSet = new TreeSet<>();
//遍历num1
for (int num : num1)
treeSet.add(num);//将num1的元素放到集合中
//新建一个动态数组(长度变化)
ArrayList<Integer> arrayList = new ArrayList<>();
//遍历num2
for (int num : num2) {
if (treeSet.contains(num))//如果包含这个元素
{//将该元素添加到数组里
arrayList.add(num);
//并且在集合中删除该元素
treeSet.remove(num);
}
}
//定义一个整形数组,长度数arrayList的长度用于返回结果
int[] arr = new int[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++)
arr[i] = arrayList.get(i);//将list里面的元素赋值给数组arr
return arr;
}
测试用例
public static void main(String[] args){
int[] num1={1,2,2,1,3,3};
int[] num2={2,2,3,5};
System.out.println("两个数组的交集为:"+Arrays.toString(intersection(num1,num2)));
}
结果:
两个数组的交集为:[2, 3]
350. 两个数组的交集
给定两个数组,写一个方法来计算它们的交集。
例如:
给定 nums1 = [1, 2, 2, 1]
, nums2 = [2, 2]
, 返回 [2, 2]
.
注意:
- 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
- 我们可以不考虑输出结果的顺序。
跟进:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
- 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
- 如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?
解题思路:返回结果是没有元素重复出现的次数,使用Map(Key,Value)(映射)来解决,映射可以通过key来记录值,value来记录元素出现的个数,每次出现一个value+1即可,在输出结果的时候没输出一个value要进行减一,知道value值为0,全部元素都输出完了
首先,将数组num1遍历,放到TreeMap中,注意(如果不加判断),TreeMap会去重的,所以每次添加元素钱Map中是否存在元素,如果存在,则要更新key的value值(value+1),如果没有,直接添加
其次,将数组2遍历,看TreeMap中是否包含有数组2的元素,如果有将这个数存放list里,并对它的value值减1,如果value值为0,则在TreeMap中删除这个元素。
public class Solution_350 {
public static int[] intersection(int[] num1, int[] num2) {
TreeMap<Integer, Integer> treeMap = new TreeMap<>();
for (int num : num1) {
if (!treeMap.containsKey(num))//如果没有这个元素
treeMap.put(num, 1);//1是第一次出现
else
treeMap.put(num, treeMap.get(num) + 1);//如果有这个元素,记录值加1
}
ArrayList<Integer> arrayList = new ArrayList<>();
//遍历num2
for (int num : num2) {
if (treeMap.containsKey(num)) {//如果map不包含这个元素
arrayList.add(num);//取出num添加到list中
treeMap.put(num, treeMap.get(num) - 1);//记录值减1
if (treeMap.get(num) == 0) //当着元素的次数全部取出来后,移除这个元素
treeMap.remove(num);
}
}
//定义一个数组装返回的结果
int[] arr = new int[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++)
arr[i] = arrayList.get(i);//将list的值赋值给arr,返回结果
return arr;
}
测试用例:
public static void main(String[] args){
int[] num1={1,2,2,1,3,3};
int[] num2={2,2,3,3,5};
System.out.println("两个数组的交集为:"+ Arrays.toString(intersection(num1,num2)));
}
输出结果:
两个数组的交集为:[2, 2, 3, 3]