1.模型
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),所以模型会有两种:
- 纯 key 模型,即我们 Set 要解决的事情,只需要判断关键字在不在集合中即可,没有关联的 value;
- Key-Value 模型,即我们 Map 要解决的事情,需要根据指定 Key 找到关联的 Value。
2 Map的使用
我们需要第一部熟悉map的一个结构,在<>内存放的是我们的一个键值对为包装类
例:<Integer,String> 其次我们来了解一个下它的一些方法
map.put()
因为我们是一个键值对就会有两个相对应的值Key Value put代表我们需要按找你的键值对类型我们来相对应的进行添加。
map.get()
get它是去get我们的Key 从而去得到相应的Value。get在的返回值即是你value的类型。
map.getOrDefault()
表达的意思就是我们如果找不到我们Key所对应的value时,会输出我们的自己定义的。
例:map.getOrDefault(80,“Jdbc”)
map.remove()
我们会根据输入的Key值,去进行删除。也是具有返回值,跳转到源码查看找返回值。
map.keySet()
会将所有的key全部提取放入到我们Set集合中。
Set set=map.keySet();
Collection collections=map.values();
表示会将我们所有的value全部提取放入到我们的一个Set之中。
遍历Map
我们使用foreach来遍历
for (Map.Entry<Integer,String> entry:map.entrySet()) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
2.Set的使用
查看set的常见方法
集合当中的元素是不能重复的。
Set < String > set=new HashSet<>();
set.add()
添加我们< String>类型的元素,无序的,其他的包装类都可以
迭代器遍历Set
Set<String> set=new HashSet<>();
set.add("q");
set.add("w");
set.add("e");
set.add("r");
System.out.println(set);
//如果要使用迭代器来遍历我们需要看他是否实现了Iterator接口
//如果要实现map的话需要将Hashmap中的所有元素放入的Set中来遍历
Iterator iterator= set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
只出现一次的数字题:
class Solution {
public int singleNumber(int[] nums) {
/*
首先思路是我们先将数组中的元素遍历
建立一个集合,如果遍历的数字中元素现在存在与集合中,
我们直接需要将元素从set中进行删除,如果发现此元素在集合中是不存在的,
最后其实,现在在集合中就是没有重复的元素我你们需要查看一下集合中的是什么数据,
此时再次使用数值遍历,如果找到数组中与set中一样的我们进行输出数组的元素
*/
Set<Integer>set=new HashSet<>();
for(int i=0; i<nums.length;i++){
if(set.contains(nums[i])){
set.remove(nums[i]);
}else{
set.add(nums[i]);
}
}
for(int j=0;j<nums.length;j++){
if(set.contains(nums[j])){
return nums[j];
}
}
return -1;
}
//另一个简单的是进行异或比较
int tmp=0;
for(int i=0;i<nums.length;i++){
tmp^=nums[i];
}
System.out.println(tmp);
return tmp;
}
复制带随机指针的链表题
/*
// Definition for a Node.
class Node {
public int val;
public Node next;
public Node random;
public Node() {}
public Node(int _val,Node _next,Node _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
class Solution {
public Node copyRandomList(Node head) {
//判断我们的头是不为空
if(head==null){
return null;
}
//我们定义的K V两个都是节点 我们要使用map就是将老的节点全部进行
//复制然后与我们的新的进行一一对应。
Map<Node,Node>map=new HashMap<>();
Node cur=head;
while(cur!=null){
//我们只复制它的val值
Node node=new Node(cur.val,null,null);
//现在有两个一个新节点,一个节点对应
map.put(cur,node);
cur=cur.next;
}
cur=head;
//此时我们需要再次进行遍历,此次的遍历的目的是将所有的几点串起来
while(cur!=null){
map.get(cur).next=map.get(cur.next);
map.get(cur).random=map.get(cur.random);
cur=cur.next;
}
//最后返回我们的头结点
return map.get(head);
}
}
3.宝石和石头
class Solution {
public int numJewelsInStones(String J, String S) {
//这个题我们需要遍历掉两个字符串,将第一个字符串的元素放入到一个集合之中
//然后在使用set.contains这个方法找到第二个字符串中有多少个和第一个中相同的,
//有一个计数器最后输出就可以了
Set<Character> set=new HashSet<>();
for(int i=0;i<J.length();i++){
set.add(J.charAt(i));
}
int a=0;
for(int j=0;j<S.length();j++){
if(set.contains(S.charAt(j))){
a++;
}
}
return a;
}
}
4.坏键盘打字
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String str1=scanner.nextLine();//期望的集合
String str2=scanner.nextLine();
Set<Character> setAct=new HashSet<>();
for (char ch: str2.toUpperCase().toCharArray()) {
setAct.add(ch);
}
Set<Character> set=new HashSet<>();
for (char ch :str1.toUpperCase().toCharArray()){
//这个条件成立代表当前ch为坏掉的
if (!setAct.contains(ch)&&!set.contains(ch)){
set.add(ch);
System.out.print(ch);
}
}
}
}
5.topK
//找到一组数据当中前K个最大的元素
public static void topK(int []array,int k){
//优先级队列 匿名内部类
PriorityQueue<Integer> priorityQueue=new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;//小堆
//return o2-o1;大堆
}
});
for (int i = 0; i <array.length ; i++) {
if (priorityQueue.size()<k){
priorityQueue.add(i);
}else {
Integer top=priorityQueue.peek();
//如果找前K个最小的我们的小于号反一下
if (top!=null && top<array[i]){
priorityQueue.poll();
priorityQueue.add(array[i]);
}
}
}
System.out.println(priorityQueue);
}
public static void main(String[] args) {
int []array={1,2,3,4,5,6};
topK(array, 3);
}
前K个高频单词
class Solution {
public static List<String> topKFrequent(String [] words,int k){
List<String>ret=new ArrayList<>();
Map<String,Integer>map=new HashMap<>();
for (String s:words){
if (map.get(s)==null){
map.put(s, 1);
}else {
map.put(s, map.get(s)+1);
}
}
PriorityQueue<Map.Entry<String,Integer>>
minHeap=new PriorityQueue<>(k, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1,
Map.Entry<String, Integer> o2) {
if (o1.getValue().equals(o2.getValue())){
//频率相同
//o1.getKey() o2.getKey();
//单词频率相同按字母顺序排序
return o2.getKey().compareTo(o1.getKey());
}
return o1.getValue()-o2.getValue();
}
});
//遍历的是map
for (Map.Entry<String,Integer> entry: map.entrySet()) {
if (minHeap.size()<k){
minHeap.add(entry);
}else {
Map.Entry<String,Integer> top=minHeap.peek();
if (top!=null && top.getValue().equals(entry.getValue())){
//频率相同的单词——》字母小的放进来
if (top.getKey().compareTo(entry.getKey())>0){
minHeap.poll();
minHeap.add(entry);
}
}else {
if (top.getValue()<entry.getValue()){
minHeap.poll();
minHeap.add(entry);
}
}
}
}
for (int i = 0; i <k ; i++) {
String tmp=minHeap.poll().getKey();
ret.add(0,tmp);
}return ret;
}
public static void main(String[]args) {
String [] words={"i", "love", "leetcode", "i", "love", "coding"};
List<String> list=topKFrequent(words,2);
System.out.println(list);
}
}