자바 문법 및 알고리즘 (hash 2)

zio도미닉·2021년 10월 14일
0
post-thumbnail

알게 된 점

2개의 맵이 같은지 비교 -> equals를 사용하면 됨

  • 주로 아나그램 (순서가 바뀌어서 같은지 확인하는 문제에서 사용)
  • hashMap1.eqauls(hasMap2) -> 복잡하게 check 해줄 필요 없다.
  • 자바에는 Map의 value값이 변경되면 자동 변경되지 않는다! put으로 다시 넣어줘야 함!

TreeSet

  • 중복 제거 + 순서대로 정렬해서 나열해줌
// 오름차순 및 내림 차순
TreeSet<Integer>treeSet=new TreeSet<>(); // 오름차순 정렬
TreeSet<Integer>treeSet=new TreeSet<>(Collections.reverseOrder()); // 내림차순
// TreeSet 인덱스 접근
 첫번째와 마지막 값만 접근 가능
treeSet.first();
treeSet.last();
// 출력은? 
// TreeSet은 기본적으로 인덱스가 없기 때문에 -> forEach를 통해서 값을 뽑아야 함
        int i=0;
        for (Integer s:treeSet) {
            i++;
            if (i==m) {  //m번째 출력
                answer=s;
            }
        }

n개 중에 r개 뽑는 방법

r중 for문 이용하면 됨

  • 굳이 DFS 이용 필요 없음.
        // nPr 구하기 -> r중 for문을 돌면 됨
        for (int i=0;i<n;i++) {
            for (int j=i+1;j<n;j++) {
                for (int k=j+1;k<n;k++) {
                    int hap=arr[i]+arr[j]+arr[k];
                    treeSet.add(hap);
                }
            }
        }

문제 1.

해결방법

  1. 슬라이싱 윈도우 (초기 값 전체 넣는) + arrayList (인덱스 접근을 위해) + hashMap 사용
  2. 슬라이싱 윈도우 + 투포인터 + hashMap 사용

코드 1

    public int solution(String str, String ans) {
        int answer=0;

        // 슬라이싱 윈도우 -> 초기값 설정
        // String -> String []
        String strArr[]=str.split("");
        String ansArr[]=ans.split("");

        int size=ans.length();

        // arraylist에 넣기, 인덱스 접근하기 위해
        // 초기값 3개만 들어감
        // 초기값 -> 아나그램인지 검사
        HashMap<String,Integer>hashMap=new HashMap<>();
        HashMap<String,Integer>ansMap=new HashMap<>();
        ArrayList<String>arrayList=new ArrayList<>();
        for (int i=0;i<size;i++) {
            arrayList.add(strArr[i]);
            hashMap.put(strArr[i],hashMap.getOrDefault(strArr[i],0)+1);
            ansMap.put(ansArr[i],ansMap.getOrDefault(ansArr[i],0)+1);
        }

        // 초기값 hashMap과 ansHashMap 비교 -> eqauls로 비교 가능
        if (hashMap.equals(ansMap)) {
            answer++;
        }

        // 슬라이싱 윈도우 -> for 문 이용
        for (int i=size;i<str.length();i++) {
            // 초기값 삭제
            String temp=arrayList.remove(0);
            int value=hashMap.get(temp)-1;
            // 0이면 hashMap에서 지우기
            if (value==0) {
                hashMap.remove(temp);
            }
            else {
                // 만약 그렇지 않으면 지운값 -> Map에 넣기
                hashMap.put(temp,value);
            }

            // 자동으로 줄일수 있는 방법이 있는가?
            // hashMap.put으로 넣지 말고?!


            // 다음값을 더해준다.
            String key=strArr[i];
            arrayList.add(key);
            // hashMap에도 더해준다
            hashMap.put(key,hashMap.getOrDefault(key,0)+1);

            // 아나그램 비교
            if (hashMap.equals(ansMap)) {
                answer++;
            }

        }
        return answer;

    }

코드 2

    public int solution2(String str, String ans) {
        int answer=0;
        String []strArr=str.split("");
        String []ansArr=ans.split((""));
        HashMap<String,Integer>hashMap=new HashMap<>();
        HashMap<String,Integer>ansMap=new HashMap<>();

        for (String s:ansArr) {
            ansMap.put(s,ansMap.getOrDefault(s,0)+1);
        }

        // 초기에 슬라이싱 윈도우는 ans보다 1개 작은것 까지만 넣어줌
        for (int i=0;i< ansArr.length-1;i++) {
            hashMap.put(strArr[i],hashMap.getOrDefault(strArr[i],0)+1);
        }

        // 투포인터 및 슬라이싱 윈도우
        int lt=0; // lt가 가리키는 것은 삭제할 인덱스를 가르킴
        for (int rt=ansArr.length-1;rt< strArr.length;rt++) {
            // 처음 값을 넣어줌
            String key=strArr[rt];
            hashMap.put(key,hashMap.getOrDefault(key,0)+1);

            // 이 값이 ansMap이랑 같은지 비교
            if (hashMap.equals(ansMap)) {
                answer++;
            }

            // 초기 값 삭제
            int value=hashMap.get(strArr[lt])-1;
            if (value==0) {
                hashMap.remove(strArr[lt]);
            }
            else {
                hashMap.put(strArr[lt],value);
            }

            if (hashMap.equals(ansMap)) {
                answer++;
            }

            // 다음 인덱스를 위해 lt 증가
            lt++;
        }
        return answer;
    }

문제 2.

코드

    public int solution(int n,int m,int arr[]) {
        int answer=-1;

//        TreeSet<Integer>treeSet=new TreeSet<>(); // 오름차순 정렬
        TreeSet<Integer>treeSet=new TreeSet<>(Collections.reverseOrder()); // 내림차순

        // nPr 구하기 -> r중 for문을 돌면 됨
        for (int i=0;i<n;i++) {
            for (int j=i+1;j<n;j++) {
                for (int k=j+1;k<n;k++) {
                    int hap=arr[i]+arr[j]+arr[k];
                    treeSet.add(hap);
                }
            }
        }
        
        // TreeSet은 기본적으로 인덱스가 없기 때문에 -> forEach를 통해서 값을 뽑아야 함
        int i=0;
        for (Integer s:treeSet) {
            i++;
            if (i==m) {
                answer=s;
            }
        }
        return answer;

    }
profile
BackEnd Developer

0개의 댓글