(数组)刷题记录

0 unordered_map

  1. map与unordered_map
  • map: map内部实现了一个红黑树,红黑树具有自动排序的功能,因此map内部的所有元素都是有序的
  • unordered_map: 内部实现了一个哈希表。其元素的排列顺序是无序的
  • map:
    优点:有序性
    缺点: 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间
    适用处:对于那些有顺序要求的问题,用map会更高效一些
  • unordered_map:
    优点: 因为内部实现了哈希表,因此其查找速度非常的快
    缺点: 哈希表的建立比较耗费时间
    适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
  1. 定义:unordered_set<int>s;unordered_map<string ,int>s;
  2. 查找元素:
查找x是否在map中
    方法1:  若存在  if(mp.find(x)!=mp.end())
    方法2:  若存在  if(mp.count(x))
  1. 插入元素x:mp.insert(x)
  2. iterator->second 对于map
  • it->first会得到key,
  • it->second会得到value。

1最大子序和

/类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值 INT_MININT_MAX

2两数之和

return{}表示返回一个空的vector 。return{1,2}表示返回一个vector:[1,2]

3合并两个有序数组

i++ 是先引用后增加 ,先在i所在的表达式中使用i的当前值,后让i加1
++i 是先增加后引用,让i先加1,然后在i所在的表达式中使用i的新值
思路1:反向双指针

    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = n + m - 1;
        int p1 = m -1;
        int p2 = n - 1;
        while (p1 >= 0 and p2 >= 0) {
            if (nums1[p1] < nums2[p2]) nums1[i--]= nums2[p2--];           
            else {
                nums1[i--] = nums1[p1--];
            }         
        }
        while (p1 >= 0) nums1[i--] = nums1[p1--];
        while (p2 >= 0) nums1[i--] = nums2[p2--];      
    }

4 两个数组的交集 II

统计nums1中每个元素出现的次数

unordered_map <int, int> m;
for (int num : nums1) {
            ++m[num]; //
        }

在这里插入图片描述

5 杨辉三角

6 重塑数组

获取二维数组v的行和列:

  • int row = v.size();

  • int col =v[0].size();

在这里插入图片描述
思路:对于m×n的矩阵V1转换为r*c的矩阵V2,
在这里插入图片描述

7合并两个数组

方法一:insert

vector<string>vec1,vec2,vec3;
//... vec1,vec2赋值
vec3.insert(vec3.end(),vec1.begin(),vec1.end());
vec3.insert(vec3.end(),vec2.begin(),vec2.end()); 

方法二:merge()
[注]:

  • 合并后的数组需要提前指定好大小
  • 合并的两个数组必须有序
vector<string>vec1,vec2,vec3;
//... vec1,vec2赋值
sort(vec1.begin(),vec1.end());
sort(vec2.begin(),vec2.end());
vec3.resize(vec1.size()+vec2.size());
merge(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),vec3.begin());

1二分查找

前提:数组为有序数组,同时题目还强调数组中无重复元素
[l,r] : while (left <= right) r = mid - 1
[l,r) while (left < right) r = mid;

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

2 二分查找-II

有重复数字的升序数组的二分查找,返回出现targer的第一个数组下标
找到target后,只要mid>=0且nums[mid - 1]也等于target,就mid–,直至找到第一个。

    int search(vector<int>& nums, int target) {
        // write code here
        int l = 0, r = nums.size() - 1;
        while (l <= r) {
            int mid = ((r - l) >> 1) + l;
            if (nums[mid] == target) {
                while (mid != 0 and nums[mid - 1] == target) mid--;
                return mid;
            }
            else if (nums[mid] > target) r = mid - 1;
            else {
                l = mid + 1;
            }
        }
        return -1;
    }

3 求平方根

满足有序和无重复元素
除0以外,所有非负整数的平方根都在1-它本身之间
因为取整,所以取整后的平方根res,res²<x, (res+1)² >x

  • 因此左边界l=1,右边界r= x。边界条件l<= r,能取等号的原因:例如l=1=x,也可以进行下面的操作。
  • 求出中间值,若中间值的平方>x,说明中间值大了,此时应该缩小右边界r = mid - 1;
  • 中间值的平方<x,且中间值+1的平方>x,则说明就是所求的平方根,否则说明中间值小了,应该增大左边界l=mid+1;
    int mySqrt(int x) {
        int l = 1, r = x;
        while (l <= r) {
            int mid =((r - l) >> 1)  + l;
            if (mid > x / mid) {
                r = mid - 1;
            }
            else {
                if (mid + 1 > x / (mid + 1)) return mid;
                l = mid + 1;
            }
        }
        return 0;
    }

位运算

1 左移运算符<<:左移第一个操作数的位,第二个操作数确定要移位的位数。或者换句话说,将整数“ x”与整数“ y”(x << y)左移等效于将x乘以2 ^ y(2乘幂y)。

2 右移运算符>>:取两个数字,右移第一个操作数的位,第二个操作数决定移位的位数。类似地,右移(x >> y)等于将x除以2 ^ y。

3 异或运算 ^xor
0^0=0; 0^1=1; 1^0=1; 1^1=0;
性质:
a.满足交换律
b 两个一样的数异或结果为0
c 0 xor n = n

4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值