【重要的事情写在前面】
先来说说swap的实现方式,这道题我本来自己写了个swap的算法,除了通常的
swap(type& a, type& b){
type t = a;
a = b;
b = a;
}
的写法外,还有一种【极客】写法:
swap(type& a, type& b){
a ^= b;
b ^= a;
a ^= b;
}
以上两种写法在swap(x, x)时不等价!
也就是第一种写法在swap同一个元素时能得到想要结果(元素跟自己交换就相当于没有交换),但第二种写法swap同一个元素时会把该元素置0!看看算法实现就明白了,用的时候要小心,或者干脆就用标准库函数,别炫技巧挖坑给自己跳!
或许写成这样
swap(type& a, type& b){
if(a != b){
a ^= b;
b ^= a;
a ^= b;
}
}
就行了,但一般来说,这种方法并不比上面那种使用临时变量的方法快,主要原因有两点:
1.现代编译器会优化掉第一种方法中的临时变量,也就是他并不比异或方式空间开销大。
2.异或方式因为数据依赖性会降低处理器指令流水线并行度。
说明见这里:https://en.wikipedia.org/wiki/XOR_swap_algorithm#Reasons_for_avoidance_in_practice
以下是题目
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
在一个乱序数组中寻找第k大的元素,一种方法是利用快排的partition策略,每次partition后比较枢轴位置是不是第k大元素的位置,不是的话也能减少一半搜索范围,代码如下:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { int left = 0, right = nums.size() - 1; while(true){ int pivot = partition(nums, left, right); if(pivot == k - 1) return nums[pivot]; if(pivot < k - 1){ left = pivot + 1; }else{ right = pivot - 1; } } } int partition(vector<int>& nums, int left, int right){ int pivot = nums[right]; int j = left - 1; for(int i = left; i <= right; ++i){ if(nums[i] >= pivot){ //myswap(nums[++j], nums[i]); swap(nums[++j], nums[i]); } } return j; } //这里的swap用这种实现是错的! void myswap(int& a, int& b){ a ^= b; b ^= a; a ^= b; } };
以下是使用最大堆的解法:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { build_max_heap(nums); for(int i = 0; i < k; ++i){ swap(nums[0], nums[--heap_size]); max_heapify(nums, 0); } return nums[heap_size]; } inline int parent(int idx){ return (idx - 1) >> 1; } inline int left(int idx){ return (idx << 1) + 1; } inline int right(int idx){ return (idx << 1) + 2; } void max_heapify(vector<int>& nums, int idx){ int largest = idx; int l = left(idx), r = right(idx); if(l < heap_size && nums[largest] < nums[l]) largest = l; if(r < heap_size && nums[largest] < nums[r]) largest = r; if(largest != idx){ swap(nums[largest], nums[idx]); max_heapify(nums, largest); } } void build_max_heap(vector<int>& nums){ heap_size = nums.size(); for(int i = parent(heap_size - 1); i >= 0; --i){ max_heapify(nums, i); } } private: int heap_size; };
用标准库模板更简单:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { priority_queue<int> pq(nums.begin(), nums.end()); while(--k > 0){ pq.pop(); } return pq.top(); } };
浙公网安备 33010602011771号