From 3386bf8fc1262cf8898d7957ef9198a0551c0d59 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Wed, 30 Oct 2019 19:41:43 +0800 Subject: [PATCH] Create 274. H-Index.md --- solutions/274. H-Index.md | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 solutions/274. H-Index.md diff --git a/solutions/274. H-Index.md b/solutions/274. H-Index.md new file mode 100644 index 0000000..d33053b --- /dev/null +++ b/solutions/274. H-Index.md @@ -0,0 +1,66 @@ +# [274. H-Index](https://leetcode.com/problems/h-index/) +# 思路 +这道题让我们求H指数,如果一个人的学术文章有n篇至少被引用了n次,那么H指数就是满足条件的最大的n。 + +## 思路一 +根据定义我们可以很好想到先将引用量数组从大到小排个序, 再从后往前遍历直到`i >= citations[i]`成立, 此时i就是H指数. + +## 思路二 +完整的排序复杂度是O(nlogn), 但其实我们没必要排序, 只需要用快排partition的思想不断划分, 例如我们按照从小到大的顺序划分, +若某次划分点索引为k: +* 若 `n - k == citations[k]`, 说明有citations[k]个论文引用量大于等于citations[k], 返回citations[k]即可. +* 否则若`n - k > citations[k]`, 说明结果在右边; +* 否则, 说明结果是citations[k]或左边. + +注意边界条件. + +# C++ +## 思路一 +``` C++ +class Solution { +public: + int hIndex(vector& citations) { + int n = citations.size(); + if (!n) return 0; + sort(citations.begin(), citations.end(), greater()); + int i = 0; + for (; i < n; i++) + if(i >= citations[i]) break; + + return i; + } +}; +``` + +## 思路二 +``` C++ +class Solution { +private: + // 标准的快排划分(非常重要) + int partition(vector &arr, int left, int right){ + int pivot = arr[left]; + while(left < right){ + while(left < right && pivot <= arr[right]) right--; + arr[left] = arr[right]; + while(left < right && pivot >= arr[left]) left++; + arr[right] = arr[left]; + } + arr[left] = pivot; + return left; + } +public: + int hIndex(vector& citations) { + int n = citations.size(); + int left = 0, right = n - 1; + while(left <= right){ + if(left == right) return min(citations[left], n - left); + + int k = partition(citations, left, right); + if(n - k == citations[k]) return citations[k]; + if(n - k > citations[k]) left = k + 1; + else right = k; + } + return 0; + } +}; +```