목차
해시 테이블
주로 해시 맵의 키-값 쌍 기능을 사용하여 데이터 를 처리합니다.
개인이 요약 한 일반적으로 사용되는 코드 조각 :
맵의 키에 해당하는 값을 +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;
}
}