Open ami-ryu opened 5 years ago
i) 전체배열을 작게 분할하여 분할된 배열내에서 중간값을 찾는다. ii) 각각의 분할된 배열내의 중간값들에서 중간값을 한번 더 찾는다. 그렇다면, 이는 대략적인 중간값일 것이다.
퀵정렬을 설계할 때 Pivot을 선택하는 방법에는 여러가지가 있지만, 대표적으로는 임의의 한 원소를 선택하는 방법과 처음, 중간, 끝의 원소 중 중앙값인 원소를 선택하는 방법의 두 가지가 있다.
퀵정렬에서 써먹을 수 있도록 세 수 중에서 중앙값을 찾는 방법을 생각해보자. 기본적인 방법은, 다량의 조건문을 이용해 찾는 것이다.
int median(int a, int b, int c){
if (a > b){
if (b > c) return b;
else if (a > c) return c;
else return a;
}
else{
if (a > c) return a;
else if (b > c) return c;
else return b;
}
}
조건부 연산자(exp?exp:exp)를 이용하면 코드가 좀 더 짧아지겠지만, 해석하기 어려워 진다.
교환 법칙이 성립되는 XOR의 성질을 이용한다면, 분기 없이 중앙값을 찾을 수도 있다.
int median(int a, int b, int c){
int maximum = max(max(a, b), c);
int minimum = min(min(a, b), c);
return a ^ b ^ c ^ maximium ^ minimum;
}
세 수 모두를 XOR로 결합하고, 다시 최대값 최소값을 XOR로 제외함으로써 중앙값을 구했다.
중요. 위에 문제와 관련해서 생각해보면, length 를 이미 알고있으므로 length/2 를 찾으면 됨.
[1, 3, 5, 5, 7, 7, 9] k = 4
일단 퀵소트는 unstable stable 한 소팅 종류에는 Merge, Bubble, Insertion, Selection 이 있으니까.... 이런 소팅을 해서 구하면 되지 않을까?
http://1ambda.github.io/algorithm/design-and-analysis-part1-2/
아마도 인풋은 [10, 20, 30, 50, 100] [10, 20, 50, 100, 150]
각 거주민이 우편물까지의 거리의 전체 합이 최소가 되어야겠지.
얘네의 중간값을 찾는다고 꼭 최적인것은 아닐테고.. 음
DP 같이 풀어야하나?
[1명, 3명, ..] 이라면 [1, 3, 3, 3, ... ] 이런식으로 배열을 새로 만들어서 중간값을 찾는다.
Leetcode / p. 153
풀이 https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60306/Python-different-solutions-with-comments-(bubble-sort-selection-sort-heap-sort-and-quick-sort).
1) sorted 내장함수 : O(nlogn)
2) Bubble Sort : O(nk)
⭐️ 3) Quick Selection : O(n)
def findKthSmallest(self, nums, k): if nums: pos = self.partition(nums, 0, len(nums)-1) if k > pos+1: return self.findKthSmallest(nums[pos+1:], k-pos-1) elif k < pos+1: return self.findKthSmallest(nums[:pos], k) else: return nums[pos]
choose the right-most element as pivot
def partition(self, nums, l, r): low = l while l < r: if nums[l] < nums[r]: nums[l], nums[low] = nums[low], nums[l] low += 1 l += 1 nums[low], nums[r] = nums[r], nums[low] return low