遍历
直观思考,一次遍历数组,计数 target
。用 target
出现次数和数组长度的一半做比较,即可得到答案。
class Solution {
public:
bool isMajorityElement(vector<int>& nums, int target) {
int cnt = 0;
for(auto &x:nums)
if(x == target)
cnt++;
if(cnt > nums.size() >> 1) return true;
return false;
}
};
class Solution:
def isMajorityElement(self, nums: List[int], target: int) -> bool:
cnt = 0
for i in range(len(nums)):
if target == nums[i]: cnt += 1
return cnt > len(nums) >> 1
- 时间复杂度 : O ( n ) O(n) O(n) , n n n 是数组长度 ,遍历数组的时间复杂度 O ( n ) O(n) O(n) 。
- 空间复杂度 : O ( 1 ) O(1) O(1) , 除答案使用的空间外,只使用常量级空间 。
二分查找
基于数组的有序性,通过二分查找,可以找到第一个等于 target
的数,和第一个大于 target
的数。通过下标,算出 target
在数组中的数量(长度) ,和数组长度的一半做比较,即可。
class Solution {
public:
bool isMajorityElement(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
while(l <= r) {
int mid = l + (r - l >> 1);
if(nums[mid] <= target) l = mid + 1;
else r = mid - 1;
}
int rb = l -1;
l = 0, r = nums.size() - 1;
while(l <= r) {
int mid = l + (r - l >> 1);
if(nums[mid] < target) l = mid + 1;
else r = mid - 1;
}
int lb = l;
int len = rb - lb + 1;
return len > nums.size() >> 1;
}
};
class Solution:
def isMajorityElement(self, nums: List[int], target: int) -> bool:
l, r = 0, len(nums) - 1
while l <= r:
mid = l + (r - l >> 1)
if nums[mid] <= target: l = mid + 1
else: r = mid - 1
rb, l, r = l - 1, 0, len(nums) - 1
while l <= r:
mid = l + (r - l >> 1)
if nums[mid] < target: l = mid + 1
else: r = mid - 1
lb = l
size = rb - lb + 1
return size > len(nums) >> 1
- 时间复杂度 : O ( l o g n ) O(logn) O(logn) , n n n 是数组长度 ,二分查找的时间复杂度 O ( l o g n ) O(logn) O(logn) 。
- 空间复杂度 : O ( 1 ) O(1) O(1) , 除答案使用的空间外,只使用常量级空间 。
AC
致语
- 理解思路很重要
- 读者有问题请留言,清墨看到就会回复的。