查看: 15750| 回复: 7
跳转到指定楼层
上一主题 下一主题
收起左侧

Leetcode Wiggle Sort II 求解!还没人给出过O(n)算法。。

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
大家好,求问一道题!这是leetcode上的Wiggle Sort II的原题:https://leetcode.com/problems/wiggle-sort-ii/
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....
Example:
(1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].
(2) Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].
这里不能像Wiggle Sort I 那样一次性遍历过数组只比较相邻的element。Discussion里面有人用先找中位数再swap的方法,复杂度是O(nlog(n)),而且过不了testcase [4, 5, 5, 6]。
现在OJ上貌似还没有O(n) time 和 O(1) space的方法。。。求大家一起提供思路啊!







上一篇:用appmakr做的安卓/IOS的APP放在简历上有说服力么?
下一篇:问一个关于binary search循环跳出条件的问题
🔗
mkcing 2016-1-2 10:54:36 | 只看该作者
全局:
先找中位数再swap,  算法是O(n),   找中位数, o(n) 就可以了
回复

使用道具 举报

🔗
jefferyy 2016-1-6 07:03:02 | 只看该作者
回复

使用道具 举报

🔗
mumu007 2016-1-7 03:02:04 | 只看该作者
全局:
本帖最后由 mumu007 于 2016-1-7 03:04 编辑
  1. class Solution {
  2. public:
  3.     int quickSelect(vector<int>& nums, int left, int right, int n) {
  4.         // http://www.hrwhisper.me/leetcode-wiggle-sort-ii/
  5.         if(left >= right) return nums[right];
  6.         int start = left, end = right + 1;
  7.         int mid = nums[left];
  8.         while(start < end) {
  9.             while(++start < right && nums[start] < mid) ;
  10.             while(--end > left && nums[end] > mid) ;
  11.             if(start >= end) break;
  12.             swap(nums[start], nums[end]);
  13.         }
  14.         swap(nums[left], nums[end]);
  15.         if(n == end - left + 1) return nums[end];
  16.         else if(n < end - left + 1) return quickSelect(nums, left, end - 1, n);
  17.         else return quickSelect(nums, end + 1, right, n - (end - left + 1));
  18.     }

  19.     int transformInd(int i, int len) {
  20.         if(i < (len >> 1)) return i*2+1;
  21.         else return (i - (len>>1))*2;
  22.     }

  23.     void wiggleSort(vector<int>& nums) {
  24.         
  25.         int len = nums.size();
  26.         if(len < 2) return ;
  27.         int median = quickSelect(nums, 0, len - 1, (len + 1) >> 1);
  28.         int i = 0, j = 0, k = len - 1;
  29.         while(i <= k) {
  30.             int iT = transformInd(i, len), jT = transformInd(j, len), kT = transformInd(k, len);
  31.             if(nums[iT] > median) {
  32.                 swap(nums[iT], nums[jT]);
  33.                 i++;
  34.                 j++;
  35.             }
  36.             else if(nums[iT] < median) {
  37.                 swap(nums[iT], nums[kT]);
  38.                 k--;
  39.             }
  40.             else i++;
  41.         }
  42.     }
  43. };
复制代码
c++抛砖引玉,看过楼上的原帖写的,transformInd的作用就相当于
    #define A(i) nums[(1+2*(i)) % (n|1)]// Index-rewiring.
回复

使用道具 举报

🔗
mkcing 2016-2-25 01:31:59 | 只看该作者
全局:
eat0010 发表于 2016-2-25 01:28
找中位数可以O(n)? 题目要求不能用额外memory的。

找中位数 O(n) 算法导轮上有
回复

使用道具 举报

🔗
Ran2446541820 2016-2-29 09:30:24 | 只看该作者
全局:
int transformInd(int i, int len) {
        if(i < (len >> 1)) return i*2+1;
        else return (i - (len>>1))*2;
    }
这个函数的意思是什么,不太明白,能不能解释一下
回复

使用道具 举报

🔗
citynart 2016-7-29 05:54:42 | 只看该作者
全局:
Ran2446541820 发表于 2016-2-28 17:30
int transformInd(int i, int len) {
        if(i < (len >> 1)) return i*2+1;
        else return (i ...

Index的mapping。如果是偶数长度array[0,1,2,3,4,5] --> [1,3,5,0,2,4]如果是奇数长度array[0,1,2,3,4,5,6]-->[1,3,5,0,2,4,6]其实就是(2*i + 1) % (length | 1)这个表达式。
Mapping了以后即可以把它当成sort color那样做了
参考这个博客:
http://bookshadow.com/weblog/2015/12/31/leetcode-wiggle-sort-ii/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表