1.배열과문자열
배열이나 문자열에 대한 문제들은 서로 대체 가능하다.
해시테이블은 효율적인 탐색을 위해 키를 값에 대응시킨 자료구조이다.
첫 번째 해시 테이블 구현방법
연결리스트
와해시 코드 함수
로 구현
키(문자열 혹은 다른 어떤 자료형도 가능)와 값을 해시테이블에 넣을 때 상황 1. 키의
해시 코드
를 계산키의 자료형은 보통
int
혹은long
이 된다.키의 개수는 무한한데 반해
int
의 개수는 유한하기 때문에서로 다른 두 개의 키가 같은 해시 코드를 가리킬 수 있다.
Hash(key) % array_length
와 같은 방식으로 해시 코드를 이용해 배열의 인덱스를 구한다.
서로 다른 두 개의 해시 코드가 같은 인덱스를 가리킬 수도 있다. 1. 배열의 각 인덱스에는
키
와값
으로 이루어진연결리스트
가 존재한다.충돌에 대비해서 반드시 연결리스트를 이용해야한다.
충돌
이란서로 다른 두 개의 키
가같은 해시 코드
를 가리키거나서로 다른 두 개의 해시 코드
가같은 인덱스
를 가리키는 경우를 말한다.
키에 상응하는 값을 찾기 위한 과정 1. 주어진
키
로해시 코드를 계산
2.해시 코드
를 이용해인덱스를 계산
3. 해당키에 상응하는 값
을연결리스트
에서 탐색충돌이 자주 발생하는 경우
최악의 경우의 수행 시간(Worst case runtime)
은O(N)
(N은 키의 개수)일반적으로 해시에 대해 이야기 할 때 충돌을 최소화하도록 잘 구현된 경우 탐색 시간은
O(1)
이다.
두 번째 해시테이블 구현 방법
균형 이진 탐색 트리(balanced binary search tree)
로 구현된 탐색 시간은O(logN)
크기가 큰 배열을 미리 할당해 놓지 않아도 되기 때문에 잠재적으로 적은 공간을 사용한다는 장점이 있다.
키의 집합을
특정 순서로 차례대로 접근가능한데
어떤 경우에는 이러한 기능이 유용하다.
ArrayList와 가변 크기 배열
자바의
배열(array)의 특징
배열의
길이가 고정
되어 있다.배열을
생성 시 배열의 크기를 함께 지정
해야 한다.
동적 배열
과 비슷한 자료구조가 필요한 경우ArrayList
를 사용ArrayList
의 특징필요에 따라 크기를 변화시킬 수 있다.
데이터 접근 시간(access time) O(1)
을 유지한다.배열이 가득 차는 순간, 배열의 크기를 두 배로 늘린다.
크기를 두 배 늘리는 시간 O(n)
이런 일이 빈번하게 일어나지는 않기때문에
상환 입력 시간(amortized insertion time)
으로 계산 했을 때 여전히 O(1)이 된다.
상환 입력 시간
이 O(1)인 이유?배열의 크기를 K로 늘리면 그 전에 배열의 크기는 K의 절반이었을것 이므로 K/2 만큼의 원소를 복사해야 한다.
N개의 원소를 삽입 할 때 소요되는 작업은 O(N)
이다.배열의 상황에 따라 최악의 경우에 O(N)이 소요되는 삽입 연산도 존재하긴 하지만 평균적으로 각
삽입
은O(1)
이 소요된다.
문자열의 리스트(String[])가 주어쳤을때 이 문자열들을 하나로 이어붙일 때의 수행 시간은?
문자열을 이어붙일 때마다 두 개의 문자열을 읽어 문자를 하나하나 새로운 문자열에 복사해야한다.
총 수행시간은
O(N^2)
이 된다.
StringBuilder
를 사용하는 경우가변 배열을 이용하는 경우 필요한 경우에 문자열을 복사하게끔 해준다.
면접 문제
중복이 없는가? 에 대한 문제
해시 테이블을 이용하는 방법을 강구
비트 백터가 유용한가?
O(NlogN) 시간에 풀 수 있는가? 그 해법은 무엇인가?
순열 확인 문제
두 문자열이
서로 순열관계
에 있다는 말이 무엇인지 정리해보기0(N1ogN) 시간의 해법이 하나 존재한다. 다른해법은 추가공간을 사용하지만 O(N) 시간이 걸린다.
해시테이블이 유용한가?
서로 순열관계에 있는 두 문자열은 같은 문자집합으로 이루어져있고, 그 순서만 다를 것이다. 순서도 같게 만들 수 있는가?
URL화 문제
문자열의 끝에서 시작해서 앞으로 읽어 나가면서 수정하는 것이 보통 가장 쉽다.
필요한 공백을 알아야 할지도 모른다. 하나씩 세어 볼 수 있는가?
회문 순열
모든 순열을 전부 생성할 필요가 없다. 아주 비효율적이다.
어떤 문자열이 회문의 순열일 때, 그 특성은 무엇인가?
해시 테이블을 사용해 본 적이 있는가? 0(N)시간으로 줄일 수 있다.
비트 벡터를 사용해서 공간을 줄일 수 있는가?
하나 빼기
쉬운 것부터 시작하라. 각각의 조건을 개별적으로 확인할 수 있는가?
문차를 삽입
하는 것과문자를 삭제
하는 것 사이에는 어떤 연관성이 있는 가? 따로 확인해야 할 필요가 있는가?세 가지 검증을 모두 한꺼번에 할 수 있는가?
문자열 압축
조심하라! 노드가 하나만 존재할 때도 처리했는가? 노드가 하나만 있을 때는 어떤 일이 발생하는가? 반환 값을 살짝 변경해야 할 수도 있다.
문자열을 반복해서 이어붙이지 않도록 조심하라. 아주 비효율적인 방법이다.
행렬 회전
배열을 감싸는 껍질(layer)별로 생각해보라. 특정 껍질을 회전시킬 수 있겠는가?
특정 껍질을 회전한다는 말은 네 개의 배열에서 값을 서로 바꾼다는 말이다.
배열이 두 개일 때 두 배열의 값을 맞바꿀 수 있는가? 이 방법을 네 개의 배열로 확장 할 수 있겠는가?
행렬
0을 찾을때마다 해당 행과 열을 삭제한다면, 전체 행렬이 모두 0이 될 가능성이 크다. 행렬을 수정하기 전에 0인 셀을 모두 찾기
O(N^2) 대신 O(N) 공간을 추가로 사용할 수 있겠는가? 값이 0인 셀 리스트에서 진짜로 필요한 정보는 무엇인가?
0이 돼야 할 행과 열의 리스트를 유지하기 위해서 저장 장소가 필요할 수도 있다. 주어진 행렬을 저장 장소로 사용함으로써 필요한 추가 공간을 O(1)로 줄일 수 있겠는가?
문자열 회전
한 문자열이 다른 문자열의 회전된 결과라면, 특정 지점에서 회전을 했다는 뜻이다. 예를 들어
waterbottle
의 3번째 문자에서 회전을 했다면,waterbottle
의 3번째 문자에서 잘라낸 뒤오른쪽 절반(
erbootle
)을 왼쪽 절(wat
) 이전에 놓은 것이다.firstCommonAncestor 함수는 p와 q가 같은 트리에 있고, 둘 다 null이 아닌 경우에, 이들의 첫 번째 공통 조상을 반환한다.
이전 힌트를 생각하여,
erbottlewat
뒤에erbottlewat
를 이어붙이면 어떻게 되는지 생각해보기.erbottlewaterbottlewat
가 된다.
Last updated
Was this helpful?