主成分个数 - 快排中partition的深入理解
来源:互联网 发布:守望先锋 网络同步 编辑:程序博客网 时间:2024/05/26 20:21
算法课课后习题对深化理解某一算法确实很有帮助.. 这一次课程学习了快速排序,每一次排序都涉及一个partition操作,也就是把数组分为比pivot大的部分,和比pivot小的部分。
这个题目是在线性时间内找到某一长N的数组中出现次数超过某一比例,如N/3的全部元素。
https://leetcode.com/problems/majority-element-ii/
Given an integer array of size n, find all elements that appear more than
起初一看这和partition有什么关系?确实,如果坚定这一信念会得到一个很简单的基于moore投票的算法,稳定简单(两次遍历即可):⌊ n/3 ⌋
times. The algorithm should run in linear time and in O(1) space.import java.util.List;import java.util.ArrayList;public class MajorityNumber2 { public List<Integer> majorityElement(int[] nums) { int n = nums.length; Integer n1 = null, n2 = null; int c1 = 0, c2 = 0; for (int id = 0; id < n; id++) { if(n1 != null && nums[id] == n1.intValue()) c1++; else if (n2 != null && nums[id] == n2.intValue()) c2++; else if (c1 == 0) { n1 = nums[id]; c1 = 1; } else if (c2 == 0) { n2 = nums[id]; c2 = 1; } else { c1--; c2--; } } c1 = c2 = 0; for (int id = 0; id < n; id++) { if (nums[id] == n1.intValue()) c1++; else if (nums[id] == n2.intValue()) c2++; } List<Integer> rst = new ArrayList<>(); if (c1 > n/3) rst.add(n1); if (c2 > n/3) rst.add(n2); return rst; }}
但是,其实这个问题还有一种思考方法。对于某一个元素,如果超过一定比例出现,比如说一半,那它在排好序的数组中一定会处在中间点上。
类似地,超过三分之一,那一定会出现在某一个三等分点上...
那么,类似于moore投票中找candidate的方法,我可以直接用partition找到排名在某等分点上的数,从而把所有的candidate找出来,然后再遍历一次确认这些candidate中有哪些是真的主成分。partition耗时最差是线性,总共来说时间同样是线性的
import java.util.List;import java.util.ArrayList;public class Solution { public List<Integer> majorityElement(int[] nums) { int n = nums.length; List<Integer> rst = new ArrayList<>(); if (n <= 1) { for (int i = 0; i < n; i++) rst.add(nums[i]); return rst; } if (n == 2) { rst.add(nums[0]); if (nums[0] != nums[1]) rst.add(nums[1]); return rst; } int n3thc = 0; // the n/3-th counter int n2thc = 0; // the 2n/3-th counter int n3th = select(nums, n/3); int n2th = select(nums, 2*n/3); for (int i = 0; i < n; i++) { if (nums[i] == n3th) n3thc++; else if (nums[i] == n2th) n2thc++; } if (n3thc > n/3) rst.add(n3th); if (n2thc > n/3) rst.add(n2th); return rst; } private static void swap(int[] a, int p, int q) { int tmp = a[p]; a[p] = a[q]; a[q] = tmp; } private static int partition(int[] nums, int lo, int hi) { // descending partition int i = lo + 1, j = hi; for (;;) { while (nums[lo] < nums[i] && i < j) i++; while (nums[lo] > nums[j] && i < j) j--; if (i >= j) break; swap(nums, i, j); } swap(nums, lo, j); return j; } private static int select(int[] nums, int k) { // find the k-th largest in nums int lo = 0, hi = nums.length - 1; while (lo < hi) { int j = partition(nums, lo, hi); if (j < k) lo = j + 1; else if (j > k) hi = j - 1; else return nums[k]; } return nums[k]; }}
0 0
- 主成分个数 - 快排中partition的深入理解
- 主成分分析(PCA)的理解
- 机器学习算法笔记系列之深入理解主成分分析PCA-原理篇
- 机器学习算法笔记系列之深入理解主成分分析PCA-Python实现篇
- 机器学习算法笔记系列之深入理解主成分分析PCA
- 机器学习算法笔记系列之深入理解主成分分析PCA-原理篇
- 主成分分析 PCA 理解
- 主成分分析——PCA的理解
- 对主成分分析(PCA)算法的理解2
- 浅谈对主成分分析(PCA)算法的理解
- 浅谈对主成分分析(PCA)算法的理解
- 浅谈对主成分分析(PCA)算法的理解
- 对KLT,主成分分析(PCA)算法的理解
- 浅谈对主成分分析(PCA)算法的理解
- 主成分分析(PCA)的数学原理理解
- 主成分分析PCA之协方差矩阵的理解
- parallelize中指定partition个数的详解
- PCA主成分分析简单理解
- RESTful API 设计最佳实践(6)
- 2016秋 学习笔记2
- 偏函数
- 【t044】弗洛伊德
- C语言实践--day1
- 主成分个数 - 快排中partition的深入理解
- 从零开始ASP.NET MVC(一)
- js判断对象是否相等
- 一次jVM性能调优记录
- PHP中的生成XML文件的4种方法
- 放硬币问题的解空间结构
- 问题,sublime在python上面,为什么input不能用
- 2017网易C++笔试:将构造函数补充完整
- java--JAXP对xml文档的解析