1、搜索旋转排序数组
暴力枚举
速度反而更快。。。。。。
int search(vector<int>& nums, int target) {
for(int i=0;i<nums.size();i++){
if(nums[i]==target){
return i;
}
}
return -1;
}
二分查找
int search(vector<int>& nums, int target) {
int n=nums.size();
int l=0;
int r=n-1;
if (n == 0) {
return -1;
}
if (n == 1) {
return nums[0] == target ? 0 : -1;
}
while(l<=r){
int mid=(l+r)>>1;
if(nums[mid]==target){
return mid;
}
if(nums[l]<=nums[mid]){//前半部分有序,后半部分可能有序可能无序
//这里的l和下一行的l也可为0,但写成l更好理解
if(target>=nums[l]&&target<nums[mid]){//且目标在前半部分中
r=mid-1;//在前半部分找
}
else{
l=mid+1;//否则在后半部分找
}
}
else{//后半部分有序,前半部分可能有序可能无序
if(target>nums[mid]&&target<=nums[n-1]){//且目标在后半部分中
l=mid+1;//在后半部分找
}
else{
r=mid-1;//否则前半部分找
}
}
}
return -1;
}
2、搜索旋转排序数组Ⅱ
暴力枚举
bool search(vector<int>& nums, int target) {
for(int i=0;i<nums.size();i++){
if(nums[i]==target){
return true;
}
}
return false;
}
二分查找
将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。 此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环.
bool search(vector<int>& nums, int target) {
int n=nums.size();
int l=0;
int r=n-1;
if (n == 0) {
return false;
}
if(n==1){
return nums[0] == target;
}
while(l<=r){
int mid=(l+r)>>1;
if(nums[mid]==target) return true;
if(nums[l]==nums[mid]&&nums[r]==nums[mid]){
l++;
r--;
}
else if(nums[l]<=nums[mid]){//要写 else if
if(target>=nums[l]&&target<nums[mid]){
r=mid-1;
}
else{
l=mid+1;
}
}else{
if(target>nums[mid]&&target<=nums[n-1]){
l=mid+1;
}
else{
r=mid-1;
}
}
}
return false;
}
寻找旋转排序数组中最小值
暴力枚举
int findMin(vector<int>& nums) {
int minval=nums[0];
for(int i=0;i<nums.size();i++){
minval=min(nums[i],minval);
}
return minval;
}
二分查找
int findMin(vector<int>& nums) {
int n=nums.size();
int l=0;
int r=n-1;
while(l<=r){
int mid=(l+r)>>1;
if(nums[r]>nums[mid]){
r=mid;
}else{
l=mid+1;
}
}
return nums[r];
}
爬楼梯
int climbStairs(int n) {
int f[46];
f[0]=1;
f[1]=1;
for(int i=2;i<=n;i++){
f[i]=f[i-1]+f[i-2];
}
return f[n];
}
斐波那契数列
int fib(int n) {
int f[31]={0,1};
for(int i=2;i<=n;i++){
f[i]=f[i-1]+f[i-2];
}
return f[n];
}
泰波那契数
int tribonacci(int n) {
int t[39]={0,1,1};
for(int i=3;i<=n;i++){
t[i]=t[i-1]+t[i-2]+t[i-3];
}
return t[n];
}
差的绝对值为k的数对数目
暴力
int ans=0;
for(int i=0;i<nums.size();i++){
for(int j=i+1;j<nums.size();j++){
if(abs(nums[i]-nums[j])==k){
ans++;
}
}
}
return ans;
}
哈希表加一次枚举
int countKDifference(vector<int>& nums, int k) {
unordered_map <int,int> cnt;
int ans=0;
int n=nums.size();
for(int j=0;j<n;j++){
ans+=(cnt.count(nums[j]-k)?cnt[nums[j]-k]:0);
ans+=(cnt.count(nums[j]+k)?cnt[nums[j]+k]:0);
++cnt[nums[j]];//记录数组中每个数
}
return ans;
}
猜数字
int game(vector<int>& guess, vector<int>& answer) {
int ans=0;
for(int i=0;i<3;i++){
if(guess[i]==answer[i]){
ans++;
}
}
return ans;
}
拿硬币
int minCount(vector<int>& coins) {
int ans=0;
for(int i=0;i<coins.size();i++){
if(coins[i]&1){
ans+=(coins[i]>>1)+1;
}
else{
ans+=coins[i]>>1;
}
}
return ans;
}
山峰数组的顶部
int peakIndexInMountainArray(vector<int>& arr) {
int n=arr.size();
int ans=0;
for(int i=0;i<n;i++){
if(arr[i]>arr[i+1]){
ans=i;
break;
}
}
return ans;
}