Kth Largest Element in an Array
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.
解法1:快排。由于我们只关心第k大的数字,因此第k个数字之前是不需要排序;即在使用快排时,只需要对包含第k个数字的序列进行排序。
class Solution {
public:
//插入排序,在元素小于20时,插入通常优于快排
void insertSort(vector<int>& a,int left, int right){
for(int i = left + 1; i <= right; i++){
int tmp = a[i];
int j = i;
for(; j > left && a[j - 1] > tmp; j--){
a[j] = a[j-1];
}
a[j] = tmp;
}
}
//找到三位中值的同时将三个数放在正确的位置
int median3(vector<int>& a, int left, int right){
int mid = (left + right) / 2;
if(a[left] > a[mid])
swap(a[left], a[mid]);
if(a[left] > a[right])
swap(a[left], a[right]);
if(a[mid] > a[right])
swap(a[mid], a[right]);
swap(a[mid], a[right-1]); //放在末尾的前一位
return a[right-1];
}
//一次快排将一个元素放置在自己的位置
void quickSort(vector<int>& a, int left, int right, int k){
int cutoff = 3;
//只有当元素个数大于等于3时才使用快排
if (right - left + 1 >= cutoff) {
int pivot = median3(a, left, right);
int i = left, j = right - 1;
while (true) {
while(a[++i] < pivot); //这里要注意a[i] = a[j] = pivot的情况,总之要先进行加减操作
while(a[--j] > pivot);
if(i < j) swap(a[i], a[j]);
else break;
}
swap(a[i], a[right-1]); //i是pivot的正确位置
if (i == k - 1) return;
else if(i < k - 1) //由于找的是第smallK小(第K大),所以有一部分是不需要排序的
quickSort(a, i + 1, right, k);
else
quickSort(a, left, i - 1, k);
}
else
insertSort(a, left, right);
}
int findKthLargest(vector<int>& nums, int k) {
int smallK = nums.size() - k + 1; //转换为第smallK小
quickSort(nums, 0, nums.size()-1, smallK);
return nums[smallK-1];
}
};
Different Ways to Add Parentheses
Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +
, -
and *
.
Example 1
Input: "2-1-1"
.
((2-1)-1) = 0 (2-(1-1)) = 2
Output: [0, 2]
解法1:递归。关键是弄清如何进行分割。
vector<int> diffWaysToCompute(string input){
int n = input.size();
vector<int> total;
for(int i = 0; i < n; i++){
char c = input[i] ;
//遇到运算符之后将字符串分开
if(c == '*' || c == '+' || c == '-'){
vector<int> result1 = diffWaysToCompute(input.substr(0, i));
vector<int> result2 = diffWaysToCompute(input.substr(i+1));
for (auto n1 : result1) {
for (auto n2 : result2) {
if (c == '+')
total.push_back(n1 + n2);
else if (c == '-')
total.push_back(n1 - n2);
else
total.push_back(n1 * n2);
}
}
}
}
// if the input string contains only number
if (total.empty())
total.push_back(atoi(input.c_str()));
return total;
}
改进:使用map<string, vector<int> >记录已计算过的结果
vector<int> diffWays(string input, unordered_map<string, vector<int> >& waysMap){
if(waysMap.find(input) != waysMap.end()) return waysMap[input];
int n = input.size();
vector<int> total;
for(int i = 0; i < n; i++){
char c = input[i] ;
//遇到运算符之后将字符串分开
if(c == '*' || c == '+' || c == '-'){
string s1 = input.substr(0, i);
string s2 = input.substr(i+1);
vector<int> result1 = diffWays(s1, waysMap);
vector<int> result2 = diffWays(s2, waysMap);
for (auto n1 : result1) {
for (auto n2 : result2) {
if (c == '+') total.push_back(n1 + n2);
else if (c == '-') total.push_back(n1 - n2);
else total.push_back(n1 * n2);
}
}
}
}
// if the input string contains only number
if (total.empty()) total.push_back(atoi(input.c_str()));
waysMap[input] = total;
return total;
}
vector<int> diffWaysToCompute(string input){
unordered_map<string, vector<int> > waysMap;
return diffWays(input, waysMap);
}