链接:
题解:
1.先用partition函数,求得n/2的位置的排序
2.然后选取首尾指针(奇数选择1和length-1,偶数选择为1和length-2),进行swap交换
3.每次首指针每次+2,尾指针每次-2
九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧
这段代码没有通过
class Solution {
public:
/**
* @param nums: A list of integers
* @return: nothing
*/
void wiggleSort(vector<int> &nums) {
// write your code here
if (nums.size() <= 1) {
return;
}
int len = nums.size();
kthLargestElement(len/2, nums);
if (len % 2 == 0) {
int left = 1;
int right = nums.size()-2;
while (left < right) {
swap(nums[left], nums[right]);
left += 2;
right -= 2;
}
} else {
int left = 1;
int right = nums.size() - 1;
while (left < right) {
swap(nums[left], nums[right]);
left += 2;
right -= 2;
}
}
}
private:
int kthLargestElement(int k, vector<int> &nums) {
cout << "k=" << k << endl;
// write your code here
if (nums.size() <= 0) {
return 0;
}
int left = 0;
int right = nums.size()-1;
int mid = partition(nums, left, right);
//cout << "mid=" << mid << endl;
while (mid != k-1) {
//cout << "mid=====" << mid << endl;
if (mid > k) {
right = mid;
} else {
left = mid;
}
mid = partition(nums, left, right);
}
return nums[mid];
}
int partition(std::vector<int>& nums, int left, int right) {
int index = random() % (right-left+1);
swap(nums[right], nums[left+index]);
int nSmall = left - 1;
for (; left < right; ++left) {
if (nums[left] <= nums[right]) {
++nSmall;
swap(nums[left], nums[nSmall]);
}
}
++nSmall;
swap(nums[right], nums[nSmall]);
cout << nSmall << " val=" << nums[nSmall] << endl;
return nSmall;
}
};
class Solution {
public:
// O(n)时间复杂度,O(1)空间
void wiggleSort(vector<int>& nums) {
if (nums.size() <= 0) {
return;
}
/*for (auto num : nums) {
cout << num << " ";
}
cout << endl;*/
int len = nums.size();
// 求得第几大的位置
// 0 1 2 3/2 = 1,假设3个数字,就是求得第2大的数字位置
// 0, 1, 2, 3 4/2 = 2,假设4个个数字,就是求得第3大的数字位置
partition(nums, 0, len-1, len/2+1);
/*for (auto num : nums) {
cout << num << " yyy ";
}*/
int left = 0;
int right = len-1;
// 如果是奇数的情况,把右边的数字排出下
if (len % 2) {
--right;
}
// 原地交换
while (left < right) {
// 交换
swap(nums[left], nums[right]);
// 空出一个位置不需要交换
left += 2;
right -= 2;
}
/*for (auto num : nums) {
cout << num << " ";
}
cout << endl;
std::vector<int> result;
result.reserve(len);
int left = 0;
int right = len-1;
while (left <= right) {
if (left == right) {
result.push_back(nums[left]);
} else {
result.push_back(nums[left]);
result.push_back(nums[right]);
}
++left;
--right;
}
nums = std::move(result);*/
}
private:
int partition(std::vector<int>& nums, int start, int end, int k) {
if (start >= end) {
return start;
}
int val = nums[start+(end-start)/2];
int l = start;
int r = end;
//cout << l << " " << val << " " << r << endl;
while (l <= r) {
while (l <= r && nums[l] < val) {
//cout << "nums" << endl;
++l;
}
while (l <= r && nums[r] > val) {
//cout << "nums" << endl;
--r;
}
if (l <= r) {
swap(nums[l], nums[r]);
//cout << "left :" << l << " " << nums[l] << " right:" << r << " " << nums[r] << endl;
++l;
--r;
}
}
if (start + k - 1 <= r) {
return partition(nums, start, r, k);
}
if (start + k - 1 >= l) {
return partition(nums, l, end, k - (l - start));
}
return r + 1;
}
};