算法学习五

26 篇文章 0 订阅

寻找峰值

力扣

class Solution {
//  看题,这个的目的是为了找到峰值
//  二分不管有序还是无序都能寻找峰值,所以直接二分

public:
    int findPeakElement(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while( l < r)
        {
            int mid = l + (r - l) /2;
            if(nums[mid] > nums[mid + 1]) r = mid;
            else l = mid + 1;
        }
        return r;
    }
};

那么 二分的模板是:(明白大概意思就行)

bool Binary_Search(int x,int n,int q[100])
{
    int l = 0, r = n - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (x == q[mid])  return true;
        if (x > q[mid])   return l = mid + 1;
         else             r = mid - 1;
    }
    return false;

x的平方根

力扣

这道题的思路什么呢:

y = \sqrt{ x }           即x = y* y           这便是题解的一个边界判断条件  

那么我们怎么去寻找y呢?

可以考虑 二分查找

二分查找 的下界为 0 ,上界可以粗略地设定为 x 。在二分查找的每一步中,我们只需要比较中间元素 mid 的平方与 x  的大小关系,并通过比较的结果调整上下界的范围。由于我们所有的运算都是整数运算,不会存在误差。

注意: 这里出现的  l +( (r - l) >> 1)——就是为了避免r,l 作为大数值 而相加 后产生的数据溢出。

同样的 x/mid 也是这个考虑。

以下附带一个大神的题解逻辑

力扣

int mySqrt(int x){
    if(x==0||x==1)  return x;
    int l = 0,r = x,mid = 0;
    while(l <= r)
    {
        mid = l +( (r - l) >> 1);
        if(mid == 0 || x/mid >= mid)   l = mid + 1;
        else                           r = mid -1;
    } 
    return l - 1;
    
}

2154. 将找到的值乘以 2 - 力扣(LeetCode) (leetcode-cn.com)

找到的值乘以2

int findFinalValue(int* nums, int numsSize, int original){
   int i;
   bool flag=true;
   while(flag){
       flag = false;
       for(int i = 0;i < numsSize;i++)
       {
        if(nums[i] == original)
         {
             flag=true;
             original *=2;
             break;
         }

       }
   }
   return original;

}

哈希表的操作

四数之和

454. 四数相加 II - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
       unordered_map<int , int>  umap;//定义一个哈希表容器来操作
      //key: a + b 的数值 ; value : a + b出现的次数;
      //而后开始遍历两个数组统计数组元素之和与出现的次数,放到umap里
       for(int a :nums1)
       {
           for(int b:nums2)
           {
               umap[a + b]++;
           }
       }
       int count=0;//用来统计 a+b+c+d = 0 出现的次数
       for(int c : nums3)
       {
           for(int d :nums4)
           {
               //遍历最后两个数组时,若 0-(c+d)在map中出现
               //则统计map中key对应的的value,即两数之和出现的次数
               if( umap.find(0 - (c + d)) != umap.end())
               {
                   count +=umap[0 - (c + d)];
               }
           }
       }
       return count;
    }
};

补充:

map和unordered_map
  map是一种有序的容器,底层是用红黑树实现的(什么是红黑树?),红黑树是一种自平衡的二叉树,可以保障最坏情况的运行时间,它可以做到O(logn)时间完成查找、插入、删除元素的操作。
  unordered_map是一种无序的容器,底层是用哈希表实现的,哈希表最大的优点是把数据的查找和存储时间都大大降低。unordered_map的迭代器是一个指针,指向容器中的元素,通过迭代器可以访问元素。

C++11标准中加入了unordered系列容器。unordered_map的底层是用哈希表(又名散列)实现。哈希表利用哈希函数,将关键字的哈希值都放在一个桶(bucket)里面,具有相同哈希值的放到同一个桶。unordered_map内部元素的存储是无序的,相当于java中的HashMap。
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值