Leetcode--ハッシュテーブルの概念の要約と古典的なトピック分析

目次

トピック1:活用句

トピック2:2つの数値の合計

トピック3:数のペアと合計

トピック4:効果的な文字バリアント単語

トピック5:現在の数に相当する数

トピック6:森の中のウサギ

トピック7:文字の頻度に従って並べ替える


ハッシュ表

    主にハッシュマップのキーと値のペア機能を使用してデータ処理します。

個人によって要約された一般的に使用されるコードの一部:

マップ内のキーに対応する値を+1変更する必要がある場合は、最初にキーに対応する値を取り出し、次に値に1を加算して、マップに戻します。

if(map.containsKey(key1)){
    int tempcount = map.get(keys)+1;
    map.put(key1,tempcount);
}

 

トピック1:活用句

(件名リンク:https//leetcode-cn.com/problems/group-anagrams-lcci

文字列の配列を並べ替え、すべてのアナグラムをグループ化するメソッドを記述します。アナグラムは、同じ文字で配置が異なる文字列です。

注:この質問は、元の質問から少し変更されています

例:

到入:["eat"、 "tea"、 "tan"、 "ate"、 "nat"、 "bat"]、
輸出出:
[
  ["ate"、 "eat"、 "tea"]、
  ["nat"、 "tan"]、
  ["bat"]
]
説明:

すべてのエントリは小文字です。
回答が出力される順序は考慮されません。

方法:データストレージにハッシュマップストレージ構造を使用します。キーに格納されている文字列には同じ文字と同じ順序が含まれ、値ストレージには同じ文字だけでなく順序も異なります。

Javaソースコード

import java.util.*;

public class hashword {
    public static void main(String[] args) {
        String[] strs = new String[]{"eat", "tea", "tan", "ate", "nat", "bat"};
        List<List<String>> strs2 = new ArrayList<List<String>>();
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for (int i = 0; i <strs.length ; i++) {
            char[] arr = strs[i].toCharArray();
            Arrays.sort(arr);
            String arrstr = new String(arr);
            if(!map.containsKey(arrstr)){
                List<String> templiststring = new ArrayList<>();
                templiststring.add(strs[i]);
                map.put(arrstr,templiststring);
            }
            else{
                map.get(arrstr).add(strs[i]);
            }
        }
        for(String key :map.keySet()){
            strs2.add(map.get(key));
        }
        System.out.println("value: "+strs2);
    }
}

最も重要な手順:

    処理する文字列を文字配列に変換してから、文字配列を並べ替えることを忘れないでください。

[注]:アイデアの要約:新しいハッシュ構造HashMap <String、List <String >>();これは私が以前に持っていなかった考え方であることに注意してください。つまり、マップのキーと値は伝統的にに対応しています。お互い。

ただし、値のデータ構造形式をlist <String>として配置します。これにより、基本的に1対多のストレージが実現されます。この種のハッシュ思考では、要約に注意が払われます。

[注]:構文の概要:文字配列を文字列に変更するには、String arrstr = new String(arr);を使用します。

                                    文字列を文字配列に変換するには、char [] arr = str.toCharArray();を使用します。

[注]:構文の概要:Arrays.sort(arr)は配列の自動ソートを実現できます

トピック2:2つの数値の合計

(件名リンク:https//leetcode-cn.com/problems/two-sum

整数配列numsと整数ターゲット値targetが与えられた場合、合計が配列内のターゲット値である2つの整数を見つけて、それらの配列添え字を返します。

各入力は1つの回答にのみ対応すると想定できます。ただし、配列内の同じ要素を2回使用することはできません。

回答は任意の順序で返すことができます。

例1:

入力:nums = [2,7,11,15]、ターゲット= 9
出力:[0,1]
説明:nums [0] + nums [1] == 9であるため、[0、1]を返します。
例2:

入力:nums = [3,2,4]、target = 6
出力:[1,2]
例3:

入力:nums = [3,3]、ターゲット= 6
出力:[0,1]

方法1:比較的単純な直接forループ、コードは表示しません

方法2:ここでは主にハッシュを使用して問題を解決する方法を説明します

公式のアイデア:ハッシュテーブルを使用して配列の値と配列のインデックスを格納します。配列の値はハッシュテーブルのキーに対応し、配列のインデックスはハッシュテーブルの値に対応します。

    forループを介して、target-nums [i]がハッシュテーブルにあるかどうかを判断します。ある場合は検出され、結果が返されます。ない場合は、num [i]とiがハッシュテーブルに格納されます。

Javaソースコード

import java.util.HashMap;
import java.util.Map;

public class twocount_sum {
    public static void main(String[] args) {
        int[] nums = new int[]{2,6,7,15};
        int target = 9;
        int result[] = new int[2];
        Map<Integer,Integer> hashtable = new HashMap<Integer,Integer>();
        for (int i = 0; i < nums.length; i++) {
            if(hashtable.containsKey(target - nums[i])){
                result[0] = i ;
                result[1] = hashtable.get(target-nums[i]);
            }else{
                hashtable.put(nums[i], i);
            }

        }
        for (int i = 0; i < 2; i++) {
            System.out.println(result[i]);
        }
    }
}

 2回目に記述されたコード:

import java.util.*;


public class Solution {
    /**
     * 
     * @param numbers int整型一维数组 
     * @param target int整型 
     * @return int整型一维数组
     */
    public int[] twoSum (int[] numbers, int target) {
        // write code here
        int[] res = new int[2];
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i =0;i<numbers.length;i++){
            map.put(numbers[i],i+1);
        }
        for(int i =0;i<numbers.length;i++){
            
            if(map.containsKey(target - numbers[i])){
                if( (i+1) != map.get(target - numbers[i])){
                    res[0] = i+1;
                res[1] = map.get(target-numbers[i]);
                break;
                }
                
            }
        }
        return res;
    }
}

トピック3:数のペアと合計

(件名リンク:https//leetcode-cn.com/problems/pairs-with-sum-lcci/

2つの数値の合計が指定された値である配列内のすべての整数ペアを検索するアルゴリズムを設計します。番号は、1つの番号ペアにのみ属することができます。

例1:

入力:nums = [5,6,5]、target = 11
出力:[[5,6]]
例2:

入力:nums = [5,6,5,6]、ターゲット= 11
出力:[[5,6]、[5,6]]

アイデア:ハッシュテーブルを使用して要素を配列に格納する

公式:公式の簡潔なコードのフォローアップ

Javaソースコード:

class Solution {
    public List<List<Integer>> pairSums(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        Map<Integer,Integer> map1 = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
            if(map1.containsKey(nums[i])){
                int tempcount = map1.get(nums[i]) +1;
                map1.put(nums[i] , tempcount);
            }else{
                map1.put(nums[i],1);
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if(map1.containsKey(target- nums[i]) ){
                if(map1.get(target - nums[i]) >0){
                    
                    //System.out.println("first: "+nums[i]+" second: "+(int)(target- nums[i]));
                    int tempcount2 = map1.get(target - nums[i])-1;
                    map1.put( target - nums[i],tempcount2);
                    if(map1.get(nums[i]) >0){
                        List<Integer> tempres = new ArrayList<Integer>();
                    tempres.add(nums[i]);
                    tempres.add((int)(target- nums[i]));
                    res.add(tempres);
                    }
                    int tempcount3 = map1.get(nums[i])-1;
                    map1.put(nums[i],tempcount3);
                }
            }

        }
        return res;
    }
}

トピック4:効果的な文字バリアント単語

(件名リンク:https//leetcode-cn.com/problems/valid-anagram/

2つの文字列sとtが与えられた場合、tがsのアナグラムであるかどうかを判別する関数を記述します。

例1:

入力:s = "anagram"、t = "nagaram"
出力:true
例2:

入力:s = "rat"、t = "car"
出力:false

方法1:文字列を文字配列に変換し、文字配列を並べ替えると、並べ替えられた文字配列が文字列になり、2つの文字列が等しいかどうかを判断します。

Javaソースコード:

class Solution {
    public boolean isAnagram(String s, String t) {
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        char[] chart = t.toCharArray();
        Arrays.sort(chart);
        if(Arrays.toString(chars).equals(Arrays.toString(chart))){
            return true;
        }else {
            return false;
        }
    }
}

方法2:配列を使用して、各文字の出現回数を決定します。

         公式の方法:最初の文字列をトラバースし、特定の文字が表示された場合、出現回数は1増加し、2番目の文字列をトラバースし、特定の文字が表示された場合、カウント回数は1つ減少します。

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] table = new int[26];
        for (int i = 0; i < s.length(); i++) {
            table[s.charAt(i)-'a']++;
        }
        for (int i = 0; i < t.length(); i++) {
            table[t.charAt(i)-'a']--;
        }
        for (int i = 0; i < 26; i++) {
            if(table[i]!=0){
                return false;
            }
        }
        return true;
    }
}

 2番目のコード

class Solution {
    public boolean isAnagram(String s, String t) {
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        int slength = s.length();
        int tlength = t.length();
        if(slength != tlength){
            return false;
        }else{
            for(int i =0;i<slength;i++){
                if(map.containsKey(s.charAt(i))){
                    int tempcount = map.get(s.charAt(i))+1;
                    map.put(s.charAt(i),tempcount);
                }else{
                    map.put(s.charAt(i),1);
                }
            }
           for(int j =0;j<tlength;j++){
               if(map.containsKey(t.charAt(j))){
                   int tempcount2 = map.get(t.charAt(j))-1;
                   map.put(t.charAt(j),tempcount2);
               }else{
                   return false;
               }
           }
           for(char key:map.keySet()){
               if(map.get(key)!=0){
                   return false;
               }
           }
           return true;
        }
    }
}

トピック5:現在の数に相当する数

(件名リンク:https//leetcode-cn.com/problems/how-many-numbers-are-smaller-than-the-current-number/

配列numsを指定します。各要素nums [i]について、配列内のそれよりも小さいすべての数値の数を数えてください。

言い換えると、各nums [i]について、有効なjの数を計算する必要があります。ここで、jはj!= iおよびnums [j] <nums [i]を満たします。

答えは配列として返されます。

例1:

入力:nums = [8,1,2,2,3]
出力:[4,0,1,1,3]
説明:  nums
[0] = 8の場合、それよりも小さい4つの数値があります:(1、2、 2および3)。 
nums [1] = 1の場合、それよりも小さい数はありません。
nums [2] = 2の場合、より小さな数があります:(1)。 
nums [3] = 2の場合、より小さな数があります:(1)。 
nums [4] = 3の場合、3つの小さい数値があります:(1、2、および2)。

アイデア:forループを直接2倍にし、暴力で解決します

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int[] res = new int[nums.length];
        for(int i =0;i<res.length;i++){
            res[i]=0;
        }
        for(int i =0; i< nums.length;i++){
            for(int j =0; j<nums.length;j++){
                if(nums[i]>nums[j]){
                    res[i]++;
                }
            }
        }
        return res;
    }
}

トピック6:森の中のウサギ

リンク:https://leetcode-cn.com/problems/rabbits-in-forest

森の中では、すべてのウサギに色があります。これらのウサギのいくつか(おそらくすべて)は、あなたと同じ色をしている他のウサギの数を教えてくれます。これらの回答を回答配列に配置します。

森の中のウサギの最小数を返します。

例:
入力:answers = [1、1、2]
出力:5
説明:
「1」と答えた2匹のウサギは、同じ色で、赤に設定されている可能性があります。
その後「2」と答えたうさぎは赤くなりません。さもないと答えが矛盾します。
「2」と答えたうさぎを青にします。
さらに、答えが配列に含まれていない森の中に他の2匹の青いウサギがいるはずです。
したがって、森の中のウサギの最小数は5です:3つは答えられ、2つは答えられません。

入力:回答= [10、10、10]
出力:11

入力:回答= []
出力:0

アイデア:主に論理の鍵を見つける:

kに答えるウサギの数をv = count [k]とすると、上記の分析から、少なくともウサギがいることがわかります。ここで、aは> = count [k]を満たす最小のk + 1倍です。 。

class Solution {
    public int numRabbits(int[] answers) {
        int res = 0;
        Map<Integer,Integer> hashtable = new HashMap<Integer,Integer>();
        for (int i = 0; i <answers.length ; i++) {
            if(hashtable.containsKey(answers[i])){
                int temp = hashtable.get(answers[i])+1;
                hashtable.put(answers[i],temp);
            }else{
                hashtable.put(answers[i],1);
            }
        }
        for (int key : hashtable.keySet()){
            for(int i =1; ;i++){
                int curr = (key+1)*i;
                if(curr >= hashtable.get(key)){
                    res = res + curr;
                    break;
                }
            }
        }
        return res;
    }
}

トピック7:文字の頻度に従って並べ替える

(リンク:https//leetcode-cn.com/problems/sort-characters-by-frequency/

文字列を指定して、文字列内の文字を出現頻度の高い順に並べ替えてください。

例1:

入力:
「ツリー」

出力:
"eert"

説明:
「e」は2回表示され、「r」と「t」はどちらも1回だけ表示されます。
したがって、「e」は「r」および「t」の前に表示する必要があります。また、「eetr」も有効な答えです。

アイデア:ハッシュテーブルを使用して各文字とその頻度を格納し、ハッシュテーブルの値に従って並べ替えて出力します

class Solution {
    public String frequencySort(String s) {
        Map<Character,Integer> hashtable = new HashMap<Character,Integer>();
        for (int i = 0; i < s.length(); i++) {
            char curr = s.charAt(i);
            if(hashtable.containsKey(curr)){
                int currcount=hashtable.get(curr)+1;
                hashtable.put(curr,currcount);
            }else{
                hashtable.put(curr,1);
            }
        }
        int[] value = new int[hashtable.size()];
        int i = 0;
        char[] key = new char[hashtable.size()];
        int j =0;
        for(Character keyi: hashtable.keySet()){
            value[i++] = hashtable.get(keyi);
            key[j++] = keyi;
        }
        //System.out.println(Arrays.toString(key));
        //System.out.println(Arrays.toString(value));
        for (int k = 0; k < value.length-1; k++) {
            for (int l = 0; l < value.length-k-1; l++) {
                if(value[l] < value[l+1]){
                    int temp = value[l];
                    value[l] = value[l+1];
                    value[l+1] = temp;
                    char temp2 = key[l];
                    key[l] = key[l+1];
                    key[l+1] = temp2;
                }
            }
        }
        String res="";
        for (int k = 0; k < key.length; k++) {
            for (int l = 0; l < value[k]; l++) {
                res += key[k];
            }
        }
        return res;
    }
}

 

おすすめ

転載: blog.csdn.net/yezonghui/article/details/112102687