링크드 리스트(linked list)의 머리 노드(head node)와 정수 N이 주어지면, 끝에서 N번째 노드(node)를 제거하고 머리 노드(head node)를 리턴하라.
단, 리스트를 한번만 돌면서 풀어야 한다. N은 리스트 길이보다 크지 않다.
예제 }
Input : 1 -> 2 -> 3 -> 4 -> 5, N = 2
Output : 1 -> 2 -> 3 -> 5
Input : 1 -> 2 -> 3, N = 3
Output : 2 -> 3
Input : 1, N = 1
Output : null
이 문제는 두 개의 포인터를 쓰면 쉽게 풀린다.
첫 번째 포인터를 먼저 N만큼 보낸다.
그리고 첫 번째 포인터와 두 번째 포인터를 동시에 하나씩 움직인다.
첫 번째 포인터의 다음 노드가 null의 값을 가지게 되면, 두 번째 포인터의 다음 노드는 끝에서 N 번째 노드가 된다.
그 노드를 제거 한 뒤 머리 노드를 리턴하면 된다.
중요한 엣지 케이스는, 첫 번째 노드를 N 번째 옮긴 후 노드의 값이 null이라면 끝에서 N 번째 노드는 첫 번째 노드임으로 헤드를 업데이트 한 후 리턴해준다.
Node solution(Node head, int n) {
if (head == null) {
return null;
}
Node first = head;
Node second = head;
for (int i = 0; i < n; i++) {
first = first.next;
}
if (first == null) {
head = head.next;
return head;
}
while (first.next != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return head;
}
정수 배열이 주어지면 0이 아닌 정수의 순서를 유지하며 모든 0을 배열의 오른쪽으로 옮겨라
예제 }
Input : [0, 5, 0, 3, -1]
Output : [5, 3, -1, 0, 0]
Input : [3, 0, 3]
Output : [3, 3, 0]
이 문제는 0을 오른쪽으로 옮기는 것보다 0이 아닌 정수를 왼쪽으로 옮긴다고 생각하면 쉽게 풀 수 있다.
void solve(int[] input) {
int position = 0; // 0이 아닌 정수가 들어갈 곳
for (int i = 0; i < input.length; i++) {
if (input[i] != 0) {
swap(input, i, position);
position++;
}
}
}
void swap(int[] arr, int a, int b) {
if (a == b) return;
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
중요한 엣지 케이스는 배열이 0 이나 1개의 원소를 가지고 있으면 두번째 큰 값이 존재 하지 않는 것과
[3, 3, 3] 같은 경우처럼 두 번째로 큰 값은 존재 하지 않는다.
이를 계산하기 위해 두 번째 큰 값을 저장할 변수를 Integer.MIN_VALUE로 두고
for루프가 끝난 뒤 값이 변했는지 체크하면 된다.
void secondLargest(int[] arr) {
int first, second;
if (arr.length < 2) {
print("두번째로 큰 값은 없습니다.");
return;
}
first = second = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
if (arr[i] > first) {
second = first;
first = arr[i];
} else if (arr[i] > second && arr[i] != first) {
second = arr[i];
}
}
if (second == Integer.MIN_VALUE) {
print("두번째로 큰 값은 없습니다.");
} else {
print(second);
}
}
이 문제는 긴 String 을 각 단어로 나눈 다음, 각 단어를 거꾸로 하고, 모든 단어들을 합치면 풀 수 있다.
public String reverseString(String s) {
String words[] = split(s);
StringBuilder res = new StringBuilder();
for (String word: words)
res.append(reverse(word) + " ");
return res.toString().trim();
}
public String[] split(String s) {
ArrayList <String> words = new ArrayList <>();
StringBuilder word = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
words.add(word.toString());
word = new StringBuilder();
} else
word.append(s.charAt(i));
}
words.add(word.toString());
return words.toArray(new String[words.size()]);
}
public String reverse(String s) {
StringBuilder res = new StringBuilder();
for (int i = 0; i < s.length(); i++)
res.insert(0,s.charAt(i));
return res.toString();
}
주로 인터뷰 중에는 split, reverse 등과 같은 언어에 포함되어 있는 함수를 쓰지 못하는 경우가 있다.