Leetcode-해시 테이블 개념 요약 및 고전적인 주제 분석

목차

주제 1 : 활용 문구

주제 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 )

문자열 배열을 정렬하고 모든 아나그램을 함께 그룹화하는 방법을 작성하십시오. 애너그램은 글자는 같지만 배열이 다른 문자열입니다.

참고 :이 질문은 원래 질문에서 약간 수정되었습니다.

예:

输入 : [ "먹다", "차", "tan", "ate", "nat", "bat"],
输出 :
[
  [ "ate", "eat", "tea"],
  [ "nat", "tan"],
  [ "bat"]
]
说明 :

모든 항목은 소문자로되어 있습니다.
답변이 출력되는 순서는 고려되지 않습니다.

방법 : 데이터 저장을 위해 해시 맵 저장 구조를 사용합니다. 여기서 키에 저장된 문자열에는 동일한 문자와 동일한 순서가 포함되고 값 저장소에는 동일한 문자와 순서가 다른 순서가 포함됩니다.

자바 소스 코드

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>으로 데이터 구조 형식의 값을 찾습니다. 이러한 종류의 해시 사고는 요약에주의를 기울입니다.

[참고] : 구문 요약 : 문자 배열을 문자열로 변경하려면 String arrstr = new String (arr);

                                    문자열을 문자 배열로 바꾸려면 char [] arr = str.toCharArray ();

[참고] : 구문 요약 : Arrays.sort (arr)는 배열의 자동 정렬을 실현할 수 있습니다.

주제 2 : 두 숫자의 합

(제목 링크 : https://leetcode-cn.com/problems/two-sum )

정수 배열 nums와 정수 대상 값 대상이 주어지면 합계가 배열의 대상 값인 두 정수를 찾아 배열 첨자를 반환합니다.

각 입력이 하나의 답변에만 해당한다고 가정 할 수 있습니다. 그러나 배열의 동일한 요소는 두 번 사용할 수 없습니다.

어떤 순서로든 답변을 반환 할 수 있습니다.

예 1 :

입력 : nums = [2,7,11,15], target = 9
출력 : [0,1]
설명 : nums [0] + nums [1] == 9이기 때문에 [0, 1]을 반환합니다.
예 2 :

입력 : nums = [3,2,4], target = 6
출력 : [1,2]
예제 3 :

입력 : nums = [3,3], target = 6
출력 : [0,1]

방법 1 : 상대적으로 간단한 Direct for 루프, 코드를 표시하지 않습니다.

방법 2 : 여기서는 주로 문제를 해결하기 위해 해시를 사용하는 방법을 설명합니다.

공식적인 아이디어 : 해시 테이블을 사용하여 배열의 값과 배열의 인덱스를 저장합니다. 배열의 값은 해시 테이블의 키에 해당하고 배열의 인덱스는 해시 테이블의 값에 해당합니다.

    for 루프를 통해 target-nums [i]가 해시 테이블에 있는지 확인합니다. 있으면 해당 항목을 찾아 결과를 반환합니다. 그렇지 않으면 num [i], i가 해시 테이블에 저장됩니다.

자바 소스 코드

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

 두 번째로 작성된 코드 :

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/ )

배열에서 두 숫자의 합이 지정된 값인 모든 정수 쌍을 찾는 알고리즘을 설계합니다. 번호는 하나의 번호 쌍에만 속할 수 있습니다.

예 1 :

입력 : nums = [5,6,5], target = 11
출력 : [[5,6]]
예제 2 :

입력 : nums = [5,6,5,6], target = 11
출력 : [[5,6], [5,6]]

아이디어 : 해시 테이블을 사용하여 배열에 요소 저장

공식 : 공식 간결한 코드에 대한 후속 조치

자바 소스 코드 :

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/ )

두 개의 문자열 s와 t가 주어지면 t가 s의 애너그램인지 여부를 확인하는 함수를 작성하십시오.

예 1 :

입력 : s = "anagram", t = "nagaram"
출력 : true
예 2 :

입력 : s = "rat", t = "car"
출력 : false

방법 1 : 문자열을 문자 배열로 변환하고 문자 배열을 정렬하면 정렬 된 문자 배열이 문자열이되고 두 문자열이 동일한 지 여부를 판단합니다 .

자바 소스 코드 :

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 씩 증가하고 두 번째 문자열을 탐색하며 특정 문자가 나타나면 계산 된 시간이 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;
    }
}

 두 번째 코드

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의 경우 (1, 2 및 2) 세 개의 더 작은 숫자가 있습니다.

아이디어 : for 루프를 직접 두 배로 늘리고 폭력으로 해결하십시오.

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

숲에서 모든 토끼는 색이 있습니다. 이 토끼 중 일부는 (아마 모두) 자신과 같은 색을 가진 다른 토끼가 몇 마리인지 알려줍니다. 이 답변을 답변 배열에 넣습니다.

숲의 최소 토끼 수를 반환합니다.

예 :
입력 : 답변 = [1, 1, 2]
출력 : 5
설명 :
"1"이라고 대답 한 두 토끼는 빨간색으로 설정되어 같은 색일 수 있습니다.
나중에 "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'는 두 번 나타나고 'r'과 't'는 모두 한 번만 나타납니다.
따라서 '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