1. LeetCode1365. 有多少小于当前数字的数字
思路:
1.使数组排序,从小到大
2.创建哈希表记录每个元素最左的下标
class Solution {
public:
vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
vector<int>vec=nums;
sort(vec.begin(),vec.end());
map<int,int>recorded;
for(int i=nums.size()-1;i>=0;i--){
recorded[vec[i]]=i;
}
for(int i=0;i<nums.size();i++){
vec[i]=recorded[nums[i]];
}
return vec;
}
};
2. LeetCode941. 有效的山脉数组
思路:
1.利用bool变量up判断现在是否在上升期
2.当第一次下降时,把up置为false,且之后都必须为false。如果下降或平地之后还有上升过程,说明就是无效的山脉
方法一:状态法
class Solution {
public:
bool validMountainArray(vector<int>& arr) {
bool up=true;
int peak=0;
for(int i=1;i<arr.size();i++){
if(arr[i-1]==arr[i]){
return false;
}
else if(arr[i-1]<arr[i]){
if(!up){
return false;
}
peak=i;
}else{
up=false;
}
}
return peak!=0&&!up;
}
};
方法二:双指针法
class Solution {
public:
bool validMountainArray(vector<int>& arr) {
int left=0;
int right=arr.size()-1;
while(left<arr.size()-1&&arr[left]<arr[left+1])left++;
while(right>0&&arr[right]<arr[right-1])right--;
return left==right&&left!=0&&right!=arr.size()-1;
}
};
3. LeetCode1207. 独一无二的出现次数
class Solution {
public:
bool uniqueOccurrences(vector<int>& arr) {
unordered_map<int,int>recorded;
set<int>count;
for(int i=0;i<arr.size();i++){
recorded[arr[i]]++;
}
for(auto &p:recorded){
if(count.find(p.second)==count.end()){
count.insert(p.second);
}else{
return false;
}
}
return true;
}
};
4. LeetCode283. 移动零
双指针:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size()==1)return;
int left=0;
int right=0;
while(left<nums.size()&&right<nums.size()){
while(left<nums.size()&&nums[left]!=0)left++;
right=left;
while(right<nums.size()&&nums[right]==0)right++;
if(left<nums.size()&&right<nums.size())swap(nums[left],nums[right]);
}
}
};
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int slowIndex=0;
for(int fastIndex=0;fastIndex<nums.size();fastIndex++){
if(nums[fastIndex]!=0){
nums[slowIndex++]=nums[fastIndex];
}
}
while(slowIndex<nums.size()){
nums[slowIndex++]=0;
}
}
};
5. LeetCode189. 轮转数组
思路:
假设以原数组的状态(即所有元素相对顺序一致)定义为有序,此种状态下,nums从0到nums.size()-1都是有序的
轮转后的数组:
1. 0~k-1有序
2. k~nums.size()-1有序
3. [0,k-1]和[k,nums.size()-1]各自有序,但二者在一起不有序
先将整体反转,这样就使得右边的能够到左边,左边的能够到右边,再以k为界限让两边局部反转,使得两边局部有序
注意:必须先让整体反转使各元素到了正确的区域,才能够局部反转使得局部有序
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k=k%nums.size();
reverse(nums.begin(),nums.end());
reverse(nums.begin(),nums.begin()+k);
reverse(nums.begin()+k,nums.end());
}
};
6. LeetCode724. 寻找数组的中心下标
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int sum=0;
for(auto&val:nums){
sum+=val;
}
int leftSum=0;
for(int i=0;i<nums.size();i++){
if(leftSum==sum-leftSum-nums[i])return i;
leftSum+=nums[i];
}
return -1;
}
};
7. LeetCode34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==1){
vector<int>vec0(2,0);
vector<int>vec1(2,-1);
return (nums[0]==target)?vec0:vec1;
}
int targetIndex=-1;
int left=0;
int right=nums.size()-1;
while(left<=right){
int mid=left+((right-left)>>1);
if(nums[mid]==target){
targetIndex=mid;
break;
}else if(nums[mid]>target){
right=mid-1;
}else{
left=mid+1;
}
}
if(targetIndex==-1){
return{-1,-1};
}else{
left=targetIndex;
right=targetIndex;
while(left>=0&&nums[left]==target)left--;
while(right<=nums.size()-1&&nums[right]==target)right++;
}
return {left+1,right-1};
}
};
8. LeetCode922. 按奇偶排序数组 II
class Solution {
public:
vector<int> sortArrayByParityII(vector<int>& nums) {
int evenIndex=0;
int oddIndex=1;
while(oddIndex<nums.size()&&evenIndex<nums.size()){
while(oddIndex<nums.size()&&oddIndex%2==1&&nums[oddIndex]%2==1)oddIndex+=2;
while(evenIndex<nums.size()&&evenIndex%2==0&&nums[evenIndex]%2==0)evenIndex+=2;
if(oddIndex<nums.size()&&evenIndex<nums.size())swap(nums[oddIndex],nums[evenIndex]);
}
return nums;
}
};
1.[left,right],闭区间
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1;
while(left<=right){
int mid=left+((right-left)>>1);
if(nums[mid]==target){
return mid;
}else if(nums[mid]<target){
left=mid+1;
}else{
right=mid-1;
}
}
return right+1;
}
};
2.[left,right),左闭右开区间
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0;
int right=nums.size();
while(left<right){
int mid=left+((right-left)>>1);
if(nums[mid]==target){
return mid;
}else if(nums[mid]<target){
left=mid+1;
}else{
right=mid;
}
}
return right;
}
};