面试题53-I:在排序数组中查找数字 I(C++)
题目地址:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/
题目描述
统计一个数字在排序数组中出现的次数。
题目示例
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
解题思路
思路1:最简单的思路是遍历nums数组,然后如果遇到与目标值相同则计数器cnt++,否则,继续遍历,直到数组末尾。
思路2:二分查找,不难看成,题目给出的数组是有序的,对于有序的数组,一般想到的就是二分查找,这里与一般二分查找有区别的是要对查找到的数target计数,所以,当查找到target时,我们需要向前和向后分别查找在mid前半部分和mid后半部分,是否有和target相同的数,如果有则cnt++。
思路3:使用哈希表计数,将待查元素target放入哈希表中,然后遍历数组计数target出现的次数,最后直接返回即可。
程序源码
暴力法
class Solution { public: int search(vector<int>& nums, int target) { if(nums.size() == 0) return 0; int cnt = 0; //计数器 for(int i = 0; i < nums.size(); i++) { if(nums[i] == target) cnt++; else continue; } return cnt; } };
二分查找
class Solution { public: int search(vector<int>& nums, int target) { if(nums.size() == 0) return 0; int left = 0, right = nums.size() - 1; int cnt = 0; //计数器 while(left <= right) { int mid = left + (right - left) / 2; if(nums[mid] < target) left = mid + 1; else if(nums[mid] > target) right = mid - 1; else { cnt++; for(int i = mid - 1; i >= left; i--) { if(nums[i] == target) cnt++; else break; } for(int j = mid + 1; j <= right; j++) { if(nums[j] == target) cnt++; else break; } break; } } return cnt; } };
哈希表
代码1
class Solution { public: int search(vector<int>& nums, int target) { if(nums.empty()) return 0; unordered_map<int, int> mp; for(auto element: nums) { mp[element]++; } for(auto num: nums) { if(num == target) return mp[num]; } return 0; } };
代码2
class Solution { public: int search(vector<int>& nums, int target) { if(nums.size() == 0) return 0; unordered_map<int, int> arr; arr[target] = 0; //target出现0次 for(int i = 0; i < nums.size(); i++) { arr[nums[i]] += 1; } return arr[target]; } };
-----------------------------------
心之所向,素履所往;生如逆旅,一苇以航。
------------------------------------------