Map与Set的经典OJ题
?前言?
📘 博客主頁:to Keep博客主頁
🙆歡迎關(guān)注,👍點贊,📝留言評論
?首發(fā)時間:2022年3月5日
📨 博主碼云地址:博主碼云地址
📕參考書籍:java核心技術(shù) 卷1
📢編程練習(xí):??途W(wǎng)+力扣網(wǎng)
由于博主目前也是處于一個學(xué)習(xí)的狀態(tài),如有講的不對的地方,請一定聯(lián)系我予以改正!!!
文章目錄
- 1 只出現(xiàn)一次的數(shù)字
- 2 復(fù)制帶隨機指針的鏈表
- 3 寶石與石頭
- 4 壞鍵盤打字
- 5 前K個高頻單詞
- 6 總結(jié)
1 只出現(xiàn)一次的數(shù)字
OJ鏈接
題目描述: 給定一個非空整數(shù)數(shù)組,除了某個元素只出現(xiàn)一次以外,其余每個元素均出現(xiàn)兩次。找出那個只出現(xiàn)了一次的元素。
解題思路:我們可以采用HashMap去做,需要遍歷兩遍數(shù)組,第一遍的時候統(tǒng)計數(shù)組中的值與出現(xiàn)的次數(shù)成一個對應(yīng)的鍵值對,第二遍的時候獲取次數(shù),如果次數(shù)為1,則就是我們要尋找的那個值
代碼如下:
class Solution {public int singleNumber(int[] nums) {HashMap<Integer,Integer> map = new HashMap<>();//第一遍遍歷數(shù)組,統(tǒng)計數(shù)組值與出現(xiàn)的次數(shù)for(int i =0;i<nums.length;i++){if(!map.containsKey(nums[i])){map.put(nums[i],1);}else{map.put(nums[i],map.get(nums[i])+1);}}//第二遍去遍歷數(shù)組,獲取數(shù)組中值所對應(yīng)的次數(shù)for(int i =0;i<nums.length;i++){if(map.get(nums[i])==1){return nums[i];}}//如果沒有次數(shù)為1的,就返回一個負(fù)數(shù)return -1;} }2 復(fù)制帶隨機指針的鏈表
OJ鏈接
題目描述:對于一個單鏈表,不僅僅有著next域,還有一個random域,要將這個鏈表進(jìn)行深拷貝一份結(jié)構(gòu)相同的單鏈表出來
解題思路:我們可以嘗試畫出復(fù)制完的兩個單鏈表,通過第一次遍歷鏈表,同時創(chuàng)建新的節(jié)點,去利用HashMap存儲舊鏈表與新鏈表之間的節(jié)點關(guān)系,第二次遍歷鏈表,將新鏈表的每個節(jié)點串起來即可
關(guān)系:
代碼如下:
3 寶石與石頭
OJ鏈接
題目描述:給你一個字符串 jewels 代表石頭中寶石的類型,另有一個字符串 stones 代表你擁有的石頭。 stones 中每個字符代表了一種你擁有的石頭的類型,你想知道你擁有的石頭中有多少是寶石。字母區(qū)分大小寫,因此 “a” 和 “A” 是不同類型的石頭。
例如:
輸入:jewels = “aA”, stones = “aAAbbbb”
輸出:3
解題思路:先遍歷jewels,利用MapSet將其存儲起來,在去遍歷stones,如果包含了stones里面的元素,說明就是寶石,計數(shù)器就要加1,否則就是石頭
代碼如下:
class Solution {public int numJewelsInStones(String jewels, String stones) {HashSet<Character> set = new HashSet<>();//遍歷jewelsfor(int i = 0;i<jewels.length();i++){set.add(jewels.charAt(i));}//遍歷stonesint count=0;//計數(shù)器for(int j = 0;j<stones.length();j++){if(set.contains(stones.charAt(j))){count++;}}return count;} }4 壞鍵盤打字
OJ鏈接
預(yù)期輸入: 7_This_is_a_test
實際輸入: _hs_s_a_es
所以壞掉的鍵有:7TI
解題思路:我們可以先把實際輸出的放到(先將字符串轉(zhuǎn)成大寫然后在變成一個數(shù)組)第一個set集合里面,第二次創(chuàng)建出一個新的set集合broken,再去遍歷預(yù)期輸入的字符串,如果第一個set里面不包含并且broken中也不包含,那么就可以打印(必須要先打印,因為set里面的元素不是按照順序放的,所以我們必須檢測到一個就要馬上打印),然后在添加到broken中。
代碼如下:
import java.util.*;public class Main {//strExce:7_This_is_a_test strActual:_hs_s_a_espublic static void func(String strExce,String strActual) {HashSet<Character> set = new HashSet<>();//將stractual變成大寫并且轉(zhuǎn)換成數(shù)組來遍歷for(char actual : strActual.toUpperCase().toCharArray()){set.add(actual);}//broken集合為了將壞掉的鍵去重,防止重復(fù)打印HashSet<Character> broken = new HashSet<>();//將strexce變成大寫,并且轉(zhuǎn)換成為數(shù)組來遍歷for(char str:strExce.toUpperCase().toCharArray()){if(!set.contains(str)&&!broken.contains(str)){System.out.print(str);broken.add(str);}}}public static void main(String[] args) {Scanner scan = new Scanner(System.in);while(scan.hasNextLine()){//由于帶有空格,所以必須是hasNextLineString str1 = scan.nextLine();String str2 = scan.nextLine();func(str1,str2);}} }5 前K個高頻單詞
OJ鏈接
題目描述:給定一個單詞列表 words 和一個整數(shù) k ,返回前 k 個出現(xiàn)次數(shù)最多的單詞。返回的答案應(yīng)該按單詞出現(xiàn)頻率由高到低排序。如果不同的單詞有相同出現(xiàn)頻率, 按字典順序 排序。
解題思路:我們先根據(jù)word與k之間,利用鍵值對,將其對應(yīng)關(guān)系存儲在map里面,然后在結(jié)合之前所學(xué)的堆,我們需要建立一個大小為K的小根堆,然后在遍歷Map,利用集合逆置輸出即可,只是在比較的過程中,需要涉及到對象的比較,需要我們指定比較方式
代碼如下:
class Solution {public List<String> topKFrequent(String[] words, int k) {//統(tǒng)計單詞出現(xiàn)的次數(shù)HashMap<String,Integer> map = new HashMap<>();for (String s:words) {map.put(s,map.getOrDefault(s,0)+1);}//建立一個小根堆PriorityQueue<Map.Entry<String,Integer>> minheap = new PriorityQueue<>(k, new Comparator<Map.Entry<String, Integer>>() {@Overridepublic int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {//如果存在放入的元素小于K,那么遇到value值一樣,應(yīng)該按照key比較if(o1.getValue().compareTo(o2.getValue())==0){return o2.getKey().compareTo(o1.getKey());}return o1.getValue()-o2.getValue();}});//遍歷map,把堆建好for (Map.Entry<String,Integer> entry:map.entrySet()) {//如果堆大小還沒有K大,那么直接放入if (minheap.size()<k){minheap.offer(entry);}else{//如果頻率相同,就要比較字符串Map.Entry<String,Integer> top = minheap.peek();if(entry.getValue().compareTo(top.getValue())==0){if(top.getKey().compareTo(entry.getKey())>0){minheap.poll();minheap.offer(entry);}}else{//按頻率比較if(top.getValue().compareTo(entry.getValue())<0){minheap.poll();minheap.offer(entry);}}}}//線性表存入StringList<String> list = new ArrayList<>();for (int i = 0; i < k; i++) {String str = minheap.poll().getKey();list.add(str);}//反轉(zhuǎn)逆置,返回線性表Collections.reverse(list);return list;}6 總結(jié)
對于以上五題,難度最大的應(yīng)該就是第五題了,比較難想到,其實就是對于考驗我們對于對象之間的比較能否掌握,以上五題整體難度一般,但能夠體現(xiàn)出set與map應(yīng)用的靈活,以及做題的優(yōu)點!!
總結(jié)
以上是生活随笔為你收集整理的Map与Set的经典OJ题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Map与Set
- 下一篇: 剑指offer(牛客)——从尾到头打印链