递归
以斐波那契数列为例:
每一层只解决本层的问题,并假设下一层的结果就是factorial(n-1)
int factorial(int n){
if(n <= 1) return 1;//第一步,确定终止条件
int m = factorial(n-1);//第二步,递归并得到返回结果
return n * m;//第三步,返回结果
}
分治(分而治之)
Pow(x, n)
Implement pow(x, n), which calculates x raised to the power n (xn).
Example 1:
Input: 2.00000, 10 Output: 1024.00000
Example 2:
Input: 2.10000, 3 Output: 9.26100
暴力法O(n)、分治法:
分解为n/2个数相乘,每个子问题又分解为n/2个数相乘。
double myPow(double x,int n){
if(n == 0) return 1;
if(n < 0) return 1/myPow(x,-n);
if(n == 1) return x;
int half = n / 2;
return myPow(x,half)*myPow(x,n-half);
}
求众数
Given an array of size n, find the majority element. The majority
element is the element that appears more than ⌊ n/2 ⌋ times.You may assume that the array is non-empty and the majority element
always exist in the array.Example 1:
Input: [3,2,3] Output: 3
参见此题的6种解法(需翻墙)
- 暴力法遍历数组,对每个元素统计个数 O(n2)
- set,将数组元素插入set,用count方法返回的最大值O(n),或map
int majorityElement1(vector<int>& nums) {//哈希 O(n) 32ms 空间O(n)
unordered_map<int,int> hash;
for(int i=0;i<nums.size();i++){
if (++hash[nums[i]]>nums.size()/2)
return nums[i];
}
}
- 对数组排序,中间的那个数就是众数O(NlogN)
int majorityElement2(vector<int>& nums) {
nth_element(nums.begin(), nums.begin() + nums.size() / 2, nums.end());
return nums[nums.size() / 2];
}
- 随机法:randomly pick an element and see if it is the majority one.
int majorityElement3(vector<int>& nums) {
int n = nums.size();
srand(unsigned(time(NULL)));
while (true) {
int idx = rand() % n;
int candidate = nums[idx];
int counts = 0;
for (int i = 0; i < n; i++)
if (nums[i] == candidate)
counts++;
if (counts > n / 2) return candidate;
}
}
- 分治法,将数组分成两半,对左边和右边都调用函数找众数。O(NlogN)
int majorityElement(vector<int>& nums) { //3 分治:left<right 返回right =则随便返回
return majority(nums, 0, nums.size() - 1);
}
int majority(vector<int>& nums, int left, int right) {
if (left == right) return nums[left];//二分到头了 返回该值
int mid = left + ((right - left) >> 1);
int lm = majority(nums, left, mid);//二分查找左半部分 lm是左半部分的结果/数值
int rm = majority(nums, mid + 1, right);
if (lm == rm) return lm;//左半部分数值等于右半部分数值 那么这个就是我们需要的
return count(nums.begin() + left, nums.begin() + right + 1, lm) > count(nums.begin() + left, nums.begin() + right + 1, rm) ? lm : rm;
// 左半部分某个数出现的多,那么就返回这个数
}
- 摩尔投票法:以1 2 3 3 4 1 1 1 1为例。指针开始指向1,遇到不一样的2,他们抵消了。指针又指向3,遇到3,计数器加1,遇到4和1,又被抵消了。指针指向1,遇到1,没被抵消。遍历完毕,剩下的1就是众数。原理就是,若众数为1,其他数为-1,和一定大于0。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int target = nums[0];
int count = 1;
for(int i = 1;i<nums.size();i++)
if(nums[i]!=target)
{
count--;
if(count==0)//count为0 则选择下一个元素为target
{
target = nums[i];
count = 1;
}
}else count++;
return target;
}
};
作者:heroine-yun
链接:https://leetcode-cn.com/problems/majority-element/solution/tong-gui-yu-jin-by-vailing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。