C++一些算法题总结

Posted Billy Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++一些算法题总结相关的知识,希望对你有一定的参考价值。

先了解一下vector,vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector是一个容器,它能够存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,可以动态改变大小。

什么是vector:

  • vector是向量类型
  • vector数组是可以存放任意数据类型的动态数组
  • 和普通数组类似,可以通过下标对数组中的元素进行引用

vector的基本操作:

声明:

vector<int> vec;

初始化:

vector<int> empty_vec();//空vec
    
vector<int> vec(3);//大小为3

vector<int> vec2(vec);//声明并用a向量初始化vec向量

int a[5] = 1, 2, 3, 4, 5;
vector<int> vec3(a, a + 5);//将a数组的元素用来初始化vec3向量

vector<int> vec4(&a[1], &a[4]);//将a[1]-a[4]范围内的元素作为vec4的初始值

vector<int> vec5 = 1, 2, 3, 4, 5, 6;
    
vector<int> vec6(5, -1);//-1,-1,-1,-1,-1

添加元素:

vec5.push_back(7);

访问元素:

for (int i = 0; i < v1.size(); i++) 
	cout << v1[i] << endl;
	v1[i] = 100;
	cout << v1[i] << endl;

for (vector<int>::iterator iter = vec5.begin(); iter != vec5.end(); iter++) 
	cout << *iter << endl;

//反向迭代
for (vector<int>::reverse_iterator iter = vec5.rbegin(); iter != vec5.rend(); iter++) 
	cout << *iter << endl;

插入元素:

std::vector<int> demo1,2;
//第一种格式用法
demo.insert(demo.begin() + 1, 3);//1,3,2
 
//第二种格式用法
demo.insert(demo.end(), 2, 5);//1,3,2,5,5
 
//第三种格式用法
std::array<int,3>test 7,8,9 ;
demo.insert(demo.end(), test.begin(), test.end());//1,3,2,5,5,7,8,9
 
//第四种格式用法
demo.insert(demo.end(),  10,11 );//1,3,2,5,5,7,8,9,10,11

删除元素:

vector<int>demo1, 2, 3, 4, 5;
demo.pop_back();
//删除最后一个元素,大小减一,容量不变
auto iter = demo.erase(demo.begin() + 1);//删除元素 2
// 删除 vector 容器中 pos 迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。
// 该容器的大小(size)会减1,但容量(capacity)不会发生改变
// erase()函数在删除元素时,会将删除位置后续的元素陆续前移,并将容器的大小减 1。

什么是set

set就是集合,STL的set用二叉树实现,集合中的每个元素只出现一次(参照数学中集合的互斥性),并且是排好序的(默认按键值升序排列),访问元素的时间复杂度是O(log₂n)。

set基本使用

begin();            // 返回指向第一个元素的迭代器

end();              // 返回指向迭代器的最末尾处(即最后一个元素的下一个位置)

clear();            // 清除所有元素

count();            // 返回某个值元素的个数
 
empty();            // 如果集合为空,返回true
 
equal_range();      //返回集合中与给定值相等的上下限的两个迭代器
 
erase()				//删除集合中的元素
 
find()				//返回一个指向被查找到元素的迭代器
 
get_allocator()		//返回集合的分配器
 
insert()			//在集合中插入元素
 
lower_bound()		//返回指向大于(或等于)某值的第一个元素的迭代器
 
key_comp()			//返回一个用于元素间值比较的函数
 
max_size()			//返回集合能容纳的元素的最大限值
 
rbegin()			//返回指向集合中最后一个元素的反向迭代器
 
rend()				//返回指向集合中第一个元素的反向迭代器
 
size()				//集合中元素的数目
 
swap()				//交换两个集合变量
 
upper_bound()		//返回大于某个值元素的迭代器
 
value_comp()		//返回一个用于比较元素间的值的函数

例题1:349. 两个数组的交集


菜鸡的思路:
桶排序。
菜鸡的代码:

class Solution 
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
        int array1[1001] = 0, array2[1001] = 0;
        vector<int> intersection;
        for (int i : nums1) 
            array1[i] = 1;
        
        for (int i : nums2) 
            if (array1[i] && !array2[i]) 
                intersection.push_back(i);
            
            array2[i]++;
        
        return intersection;
    
;

结果:

例题2:剑指 Offer 06. 从尾到头打印链表


菜鸡的思路:
vector容器反向迭代遍历。
菜鸡的代码:

class Solution 
public:
    vector<int> reversePrint(ListNode* head) 
        vector<int> normalVect, resultVect;
        ListNode* p = head;
        while (p) 
            normalVect.push_back(p->val);
            p = p->next;
        
        for (vector<int>::reverse_iterator iter = normalVect.rbegin(); iter != normalVect.rend(); iter++) 
	        resultVect.push_back(*iter);
        
        return resultVect;
    
;

结果:

例题3:905. 按奇偶排序数组


菜鸡思路:
双指针
菜鸡代码:

class Solution 
public:
    bool isOdd(int num) 
        return num % 2;
    
    vector<int> sortArrayByParity(vector<int>& nums) 
        int l = 0, r = nums.size() - 1;
        while (l < r) 
            while (!isOdd(nums[l]) && l < r) 
                l++;
            
            while (isOdd(nums[r]) && l < r) 
                r--;
            
            int t = nums[l];
            nums[l] = nums[r];
            nums[r] = t;
        
        return nums;
    
;

例题4:剑指 Offer 53 - I. 在排序数组中查找数字 I

菜鸡思路:
二分查找啊,鸡贼一点就是用自带的方法。如果是老实人就自己写吧。
菜鸡代码:

class Solution 
public:
    int search(vector<int>& nums, int target) 
        return upper_bound(begin(nums), end(nums), target) - lower_bound(begin(nums), end(nums), target);
    
;
class Solution 
public:
    int bSearch(vector<int>& nums, int target, bool low) 
        int left = 0, right = (int)nums.size() - 1, result = (int)nums.size();
        while (left <= right) 
            int mid = (left + right) / 2;
            if (nums[mid] > target || (low && nums[mid] >= target)) 
                right = mid - 1;
                result = mid;
             else 
                left = mid + 1;
            
        
        return result;
    

    int search(vector<int>& nums, int target) 
        int left = bSearch(nums, target, true);
        int right = bSearch(nums, target, false) - 1;
        if (left <= right && right < nums.size() && nums[left] == target && nums[right] == target) 
            return right - left + 1;
        
        return 0;
    
;

例题5:剑指 Offer 53 - II. 0~n-1中缺失的数字


菜鸡思路:
二分查找啊,或者使用一遍遍历。
菜鸡代码:

//二分
class Solution 
public:
//利用的就是比较该位置的值和其下标值
    int missingNumber(vector<int>& nums) 
        int left = 0, right = nums.size() - 1;
        while (left <= right) 
            int mid = (left + right) / 2;
            if (nums[mid] == mid) 
                left = mid + 1;
             else 
                right = mid - 1;
            
        
        return left;
    
;
//遍历
class Solution 
public:
//利用减值看哪个缺少
    int missingNumber(vector<int>& nums) 
        int result = (nums.size() + 1) * nums.size() / 2;
        for (int i : nums) 
            result -= i;
        
        return result;
    
;

例题6:剑指 Offer 62. 圆圈中最后剩下的数字

思考:

这道题里竟然蕴藏着动态规划的思想

代码:

class Solution 
public:
    int lastRemaining(int n, int m) 
        int x = 0;
        for (int i = 2; i <= n; i++) 
            x = (x + m) % i;
        
        return x;
    
;
开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于C++一些算法题总结的主要内容,如果未能解决你的问题,请参考以下文章

9.22“月饼杯”递归算法欢乐赛测试报告总结

算法采用递归方式实现按升序排序的选择排序算法(C++源码)

精选力扣500题 第18题 LeetCode 23. 合并K个升序链表c++详细题解

面试题打卡——C++版

面试-算法

剑指offer(C++)-JZ53:数字在升序数组中出现的次数(算法-搜索算法)