使用哈希表,找出两个字符串数组中只出现过一次的公共字符串。map中记录者字符串以及字符串出席的频次。然后在数组查找,字符串相等且频次均为1的字符串即可。
class Solution {
public:
int countWords(vector& words1, vector& words2) {
unordered_map f1,f2;
for(string str:words1){
f1[str]++;
}
for(string str:words2){
f2[str]++;
}
int res=0;
//遍历word1是否满足条件
for(auto[str,cnt1]:f1){
if(cnt1==1&&f2[str]==1){
res++;
}
}
return res;
}
};
排序+直接返回倒数第k个元素
int cmp(int* a,int* b){
return *a-*b;
}
int findKthLargest(int* nums, int numsSize, int k) {
qsort(nums,numsSize,sizeof(int),cmp);
return nums[numsSize-k];
}
本质上是找n-k位置上的元素。因为快排每趟排序都会将一个元素送到最终位置上。
class Solution {
public:
int qsort(vector& nums, int l,int r){
int mid=nums[l];
while(lmid) r--;
nums[l]=nums[r];
while(lmid) l++;
nums[r]=nums[l];
}
nums[l]=mid;
return l;
}
int findKthLargest(vector& nums, int k) {
int n=nums.size();
int l=0,r=n-1,m=0;
while(1){
m=qsort(nums,l,r);
if(m==n-k-1){
break;
}else if(m>n-k-1){
r=m-1;
}else l=m+1;
}
return nums[n-k-1];
}
};
哈希表,记录数组中各个数字出现的频次。
class Solution {
public:
vector singleNumber(vector& nums) {
unordered_map mp;
for(int num:nums){
mp[num]++;
}
vector ans;
for(auto[num,cnt]:mp){
if(cnt==1){
ans.push_back(num);
}
}
return ans;
}
};
动态规划:因为数组中存在负数,因此还得维护最小值,因为两个负值相乘有可能会产生最大值。更新时也需要用最小值和最大值分别乘nums[i]进行比较。
class Solution {
public:
int maxProduct(vector& nums) {
int n=nums.size();
if(n==0) return 0;
if(n==1) return nums[0];
int ans=nums[0];
int mmax=nums[0];
int mmin=nums[0];
for(int i=1;i
由于假设 nums[-1] = nums[n] = -∞
。因此需要单独判断只有一个元素的情况,以及第一个元素与最后一个元素。
int findPeakElement(int* nums, int numsSize) {
if(numsSize==1) return 0;
if(nums[0]>nums[1]) return 0;
if(nums[numsSize-2]nums[i+1]){
return i;
}
}
return 0;
}
给定一个无序的数组 nums
,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0
。
int cmp(int* a,int* b){
return *a-*b;
}
int maximumGap(int* nums, int numsSize) {
if(numsSize<2) return 0;
qsort(nums,numsSize,sizeof(int),cmp);
int mmax=0;
for(int i=0;immax){
mmax=cur;
}
}
return mmax;
}
排序+直接for循环进行查找
int cmp(int* a,int* b){
return *a-*b;
}
int maximumGap(int* nums, int numsSize) {
if(numsSize<2) return 0;
qsort(nums,numsSize,sizeof(int),cmp);
int mmax=0;
for(int i=0;immax){
mmax=cur;
}
}
return mmax;
}
由于数组是非递减的,用双指针向中间收缩,找到一个比target大的两数之和,由于两个数不能相等,所以low 此题与真题有些类似 第一步:排序 第二步:转化为字符串数组 排序:两个数a和b的先后,需要通过拼接后的数字进行比较,但是需要先确定a与b的位数,然后拼接时,乘上系数。 int sprintf( char *buffer, const char *format, [ argument] … ); 实际上sprintf()的作用就是把后面的字符串按照一定的格式放到从p开始的空间里。 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 示例 1:输入:strs = ["flower","flow","flight"] 输出:"fl" 此题为模拟,取出第一个字符串,然后将接下来的字符串依次与第一个进行比较,一旦发现有不一样的字符就填入终止符,代表字符串结束了。要熟悉字符串数组的这种操作。 涉及字符串操作。 sprintf(char * str,数据类型,num):将字符串变成数字类型,将单个字符变成数字的操作是 str[i]-'0' 注意不要忘,还有str[i]-‘a’这个操作也不要忘。 但是这个方法会溢出,有一半的例子通不过。 用一个辅助数组,将原数组的i位置上的元素放在(i+k)%numsSize位置,还有一种解法是原地逆置,这里先不写。 用枚举。质数就是只能除1和自己本身的数,枚举可以从2到根号n依次判断是否能够整除来判断该数是否是质数。 滑动窗口:找总和大于等于 记录前缀乘积与后缀乘积,前缀值从前到后遍历,后缀值从后到前遍历。 用动态规划,dp[i]是以从0到i的元素的最长递增子序列的长度,遍历0到i位置 判断这个数组中是否存在长度为 将此题转化为求最长递增子序列的长度,然后求的时候判断能否达到3。 从左到右遍历数组 nums,遍历过程中维护两个变量 first 和 second,分别表示递增的三元子序列中的第一个数和第二个数,任何时候都有 first 此题的困难之处在与判断两个字符串是否含有相同的字符,此处复习字符串的位运算。 由于单词只包含小写字母,共有 26个小写字母,因此可以使用位掩码的最低 26位分别表示每个字母是否在这个单词中出现。将 a 到z 分别记为第 0个字母到第 25 个字母,则位掩码的从低到高的第 i位是 1当且仅当第 i个字母在这个单词中,其中 0≤i≤25 用数组masks 记录每个单词的位掩码表示。计算数组 masks 之后,判断第 i个单词和第 j个单词是否有公共字母可以通过判断 masks[i] & masks[j]是否等于 0实现,当且仅当 masks[i] & masks[j]=0 时第 i个单词和第 j个单词没有公共字母,此时使用这两个单词的长度乘积更新最大单词长度乘积 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, 动态规划:用up,down数组进行动态, 每次更新时要判断最新的值是否能够增加摆动子序列的长度,如果不能就还是用数组的前一个值。 优化后的动态规划,不用数组而是用up和down。因为很多时候不需要进行值更新,而且只需要关注最后的那两个值即可。 给你一个整数数组 此题可以先进行排序,然后将数组逆序插入到奇数下标和偶数下标。 例如:nums = [1,5,3,2,6,4],排序之后为[1,2,3,4,5,6],逆序插入奇数下标后为[x,6,x,5,x,4,x],逆序插入偶数下标为[3,6,2,5,1,4],满足题意。 由于要子啊原数组中进行修改,故需要一个辅助数组进行记录。 如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。 例如, 用哈希表进行统计数组中出现的数字。 解题思路:动态规划: 使用贪心的思想,每次计算当前最优的子数组之和 给你一个整数数组 请你找出符合题意的 最短 子数组,并输出它的长度。 示例 1: 维护一个最大值与最小值。 int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
*returnSize=2;
int* ret=malloc(sizeof(int)*2);
int low=0,high=numbersSize-1;
while(low
179.最大数
buffer:char型指针,指向欲写入的字符串地址。
format:char型指针,指向的内存里面存放了格式字符串。
[argument]…:可选参数,可以是任何类型的数据。
返回值:字符串长度(strlen)unsigned long long cmp(int* x,int* y){
unsigned long long sx=10,sy=10;
while(sx<=*x){
sx*=10;
}
while(sy<=*y){
sy*=10;
}
return sx*(*y)+(*x)>sy*(*x)+(*y);//会溢出,排序顺序为y x
}
char* largestNumber(int* nums, int numsSize) {
qsort(nums,numsSize,sizeof(int),cmp);
if(nums[0]==0){
char *ret=malloc(sizeof(char)*2);
ret[0]='0',ret[1]='\0';
return ret;
}
char *ret=malloc(sizeof(char)*1000);
char *p=ret;
for(int i=0;i
14.最长公共前缀
""
。char* longestCommonPrefix(char** strs, int strsSize) {
if(strsSize==0) return "";
for(int i=0;i
43.字符串相乘
法一:字符串转化为整型数据
long long fun(char* str){
long long sum=0;
int n=strlen(str);
for(int i=0;i
方法二:直接同字符串模拟乘法
189.轮转数组
void rotate(int* nums, int numsSize, int k) {
int temp[numsSize];
for(int i=0;i
204.计数质数
bool isPrime(int x){
for(int i=2;i*i<=x;++i){
if(x%i==0){
return false;
}
}
return true;
}
int countPrimes(int n){
int ans=0;
for(int i=2;i
209.长度最小的连续子数组
target
的长度最小的连续子数组int minSubArrayLen(int target, int* nums, int numsSize) {
//滑动窗口
int ans=INT_MAX;
int sum=0,i=0;
for(int j=0;j
238.除自身之外的数字的乘积
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
int* res=malloc(sizeof(int)*numsSize);//结果数组
for(int i=0;i
287.寻找重复数
1.排序+遍历
int cmp(int*a,int*b){
return *a-*b;
}
int findDuplicate(int* nums, int numsSize) {
qsort(nums,numsSize,sizeof(int),cmp);
for(int i=0;i
2.哈希表
int findDuplicate(int* nums, int numsSize) {
int flag[100003]={0};
for(int i=0;i
300.最长递增子序列
#define Max(x,y) (x)>(y)?(x):(y)
int lengthOfLIS(int* nums, int numsSize) {
int dp[numsSize];//dp[i] 为考虑前i个元素,以第i个数字结尾的最长上升子序列的长度
dp[0]=1;
int ans=1;
for(int i=1;i
334.递增的三元子序列
3
的递增子序列。 1.动态规划,超时
#define Max(x,y) (x)>(y)?(x):(y)
bool increasingTriplet(int* nums, int numsSize) {
int dp[numsSize];//dp[i] 为考虑前i个元素,以第i个数字结尾的最长上升子序列的长度
dp[0]=1;
for(int i=1;i
2.贪心算法
bool increasingTriplet(int* nums, int numsSize) {
if(numsSize<3){
return false;
}
int first=nums[0],second=INT_MAX;//first与second维护时总是最小的
for(int i=1;i
318.最大单词长度乘积
int maxProduct(char ** words, int wordsSize){
int makes[wordsSize];
for(int i=0;i
376.摆动序列
[1, 7, 4, 9, 2, 5]
是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3)
是正负交替出现的int wiggleMaxLength(int* nums, int numsSize){
if(numsSize<2) return numsSize;
int up[numsSize],down[numsSize];
up[0]=1;down[0]=1;
for(int i=1;i
int wiggleMaxLength(int* nums, int numsSize){
if(numsSize<2) return numsSize;
int up=1,down=1;
for(int i=1;i
324.摆动排序II
nums
,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]...
的顺序。你可以假设所有输入数组都可以得到满足题目要求的结果。int cmp(int* a,int* b){
return *a-*b;
}
void wiggleSort(int* nums, int numsSize) {
//排序后切分成两部分然后逆序穿插
int temp[numsSize];
for(int i=0;i
413.等差数列划分
[1,3,5,7,9]
、[7,7,7,7]
和 [3,-1,-5,-9]
都是等差数列。int numberOfArithmeticSlices(int* nums, int numsSize){
if(numsSize==1) return 0;
int d=nums[0]-nums[1],t=0;
int ans=0;
for(int i=2;i
41.缺失的第一个正数
int firstMissingPositive(int* nums, int numsSize) {
int hash[100002]={0};
for(int i=0;i
53.最大连续子数组和
1. dp数组:dp[i]表示从0到i的子序列中最大序列和的值
2. 递推公式:dp[i] = max(dp[i-1] + nums[i], nums[i]),若dp[i-1]<0,对最后结果无益。dp[i]则为nums[i]。
3. dp数组初始化:dp[0]的最大子数组和为nums[0]
4. 推导顺序:从前往后遍历int maxSubArray(int* nums, int numsSize) {
int dp[numsSize];
memset(dp,0,numsSize);
int mmax=nums[0];
dp[0]=nums[0];
for(int i=1;i
int maxSubArray(int* nums, int numsSize) {
int mmax=INT_MIN;
int cur=0;//存放当前结果
for(int i=0;i
581.最短无序连续子数组
nums
,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
解法一:排序比较两个数组,记录不同值的下标
int cmp(int* a,int* b){
return *a-*b;
}
int findUnsortedSubarray(int* nums, int numsSize) {
if(numsSize<=1) return 0;
int temp[numsSize];
for(int i=0;i
解法二:一次遍历
int findUnsortedSubarray(vector