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);
}
}