数组做过的题目记录
1.数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1
第一种方法,也是我第一次实现的方法:先对数组进行排序,然后从数组头开始循环判断,步进值为数组的一半,如果当前和步进值处的数组元素是相等的,说明这个就是主要元素。
另外还有一些特殊情况,比如数组元素为0、为1、为2的时候也是易于判断的。
#include<algorithm> class Solution { public: int majorityElement(vector<int>& nums) { int len = nums.size(); if(len == 0) return -1; else if(len == 1) return nums[0]; else if(len ==2) return nums[0]==nums[1]? nums[0] : -1; sort(nums.begin(),nums.end());//使用sort方法进行从小到大的排序 //对排好序的进行判断,步进为size一半,如果还想等,说明是主要元素 for(int i=0;(i+len/2)<len;i++) { if(nums[i]==nums[i+len/2]) return nums[i]; } return -1; } };
2.数组中第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
例如:
输入:[3,2,1,5,6,4] 和
k = 2 输出: 5
#include <stdio.h> #include <vector> #include <algorithm> using namespace std; class Solution { public: int findKthLargest(vector<int> &nums, int k) { int result = 0; int numsSize = int(nums.size());//得到数组长度 if (numsSize == 0 || k > numsSize) { return 0; } //寻找第kMIN小的数 int kMin = numsSize - k + 1;//寻找第k个最大的数就是寻找第kMin个最小的数 result = select(nums, 0, numsSize - 1, kMin); return result; } int select(vector<int> &nums, int left, int right, int target) { if (left == right) { return nums[left]; } int cut = partition(nums, left, right); //当前第currentResult小的元素 int currentResult = cut - left + 1; if (target == currentResult) { return nums[cut]; } else if (target < currentResult)//如果比当前的基准值小,就在左边的部分里找 { return select(nums, left, cut - 1, target); } else { //寻找接下来第target - currentResult小的数 return select(nums, cut + 1, right, target - currentResult); } return 0; } int partition(vector<int> &nums, int left, int right) { int cut = nums[right];//算法导论里取的是这个数用来当做基准值 //i指向最左边的数,j指向下一个判断的数 int i = left; for (int j = left; j < right; j++) { if (nums[j] <= cut) { exchange(nums[i], nums[j]); i++; } } exchange(nums[i], nums[right]);//将基准值归位到第i个数 return i; } void exchange(int &a, int &b) { int tmpInt = a; a = b; b = tmpInt; return; } };
3.数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
class Solution { public: int findRepeatNumber(vector<int>& nums) { //首先可以判断特殊情况,但是题目已经给定了n>=2 //采用哈希表的思路解决这个问题。因为所有数字都在0~n-1之间,因此可以用数组的下标作为哈希表的key, //元素值作为哈希表的value,将每个key和value对应,比如key=0时存放的就是0, auto length = nums.size(); for(int i=0;i<length;i++) { while(nums.at(i)!=i) { if(nums.at(i) == nums.at(nums.at(i))) return nums.at(i); int temp = nums.at(i); nums.at(i) = nums.at(temp); nums.at(temp) = temp; } } return NULL; } };
4.数组的度
class Solution { public: int findShortestSubArray(vector<int>& nums) { unordered_map<int,int> left,right,counter; int degree = 0; for (int i = 0; i < nums.size(); i++) { if (!left.count(nums[i])) { left[nums[i]] = i; } right[nums[i]] = i; counter[nums[i]]++; degree = max(degree, counter[nums[i]]); } int length = nums.size(); for (auto& it : counter) { //对于counter里的每一个pair if (it.second == degree) { length = min(length, right[it.first] - left[it.first] + 1); } } return length; } };