C++
Sljya
这个作者很懒,什么都没留下…
展开
-
(选择排序)
选择排序 思想:先遍历一遍整个待排序数据,找到当前最大的值的 位置 。将标记的最大值与当前最后一个元素交换。重复上述过程,直到只剩下一个数据。上面的步骤每做一次,下一次就少遍历一个数据(本次找到的最大值)选择排序执行的趟数:数据元素的个数 len - 1。 时间复杂度: O(n^2) 空间复杂度: O(1) 稳定性: 不稳定 void SelectSort(int *arr, int len) { int tmp; int maxindex=0;//最大值下标 for(int i=0;i<len原创 2021-03-12 15:48:22 · 69 阅读 · 0 评论 -
(剑指offer)最小的k个数
最小的k个数 题目描述:输入整数数组 arr ,找出其中最小的 k 个数。 例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 示例: 输入:arr=[1,2,5,6,7,89,9,10],k=3 输出:[1,2,5]或[5,2,1] 思路:将原数组排序,用新数组来存储k小的数。 vector<int> getLeastNumbers(vector<int>& arr, int k) { vector<int>原创 2021-10-12 23:38:03 · 88 阅读 · 0 评论 -
(剑指offer)扑克牌中的顺子
扑克牌中的顺子 题目描述:从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。 示例1: 输入:[1,2,3,4,5] 输出:true 示例2: 输入:[1,2,2,3,4] 输出:false 思路: 1.先将数组排序。 2.判重。 排序数组中的相同元素位置相邻,因此可通过遍历数组,判断 nums[i] = nums[i + 1] 是否成立来判重。 3.排序后,找到最原创 2021-10-12 23:16:26 · 99 阅读 · 0 评论 -
(剑指offer)合并两个排序的链表
合并两个排序的链表 题目描述:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (l1 == nullptr) return l2; if (l2 == nullptr) return l1; ListNode* l3 =原创 2021-10-01 16:19:55 · 54 阅读 · 0 评论 -
(剑指offer)链表中倒数第k个节点
链表中倒数第k个节点 题目描述: 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。 例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。 示例:给定一个链表: 1->2->3->4->5, 和 k = 2.返回链表 4->5. 思路:最简单直接的方法即为顺序查找,假设当前链表的长度为 n,则我们知道链表的倒数第 k个节点即为正数第原创 2021-10-01 15:44:56 · 67 阅读 · 0 评论 -
(剑指offer)删除链表的节点
删除链表的节点 题目描述:给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。 思想:本题是删除val值,分为两步:定位节点和修改引用。 1.定位节点:遍历链表,直到找到head->val==val值时跳出,即可找到目标节点。 2.修改引用: 设节点 cur 的前驱节点为 pre ,后继节点为 cur.next ;则执行 pre.next = cur.next ,即可实现删除 cur 节点。 算法流程: 特例处理: 当应删除头节点 head 时,直接返回 h原创 2021-10-01 15:40:39 · 107 阅读 · 0 评论 -
(剑指offer) 股票的最大利润
股票的最大利润 题目描述:假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少? 思路:我们需要找出给定数组中两个数字之间的最大差值(即,最大利润)。此外,第二个数字(卖出价格)必须大于第一个数字(买入价格)。 形式上,对于每组 i和 j(其中 j > i)我们需要找出 max(prices[j] - prices[i])。 1.暴力法: int maxProfit(vector<int>& prices) { int n =原创 2021-09-26 17:09:22 · 57 阅读 · 0 评论 -
(剑指offer)青蛙跳台阶问题
青蛙跳台阶问题 题目描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 思路:设跳上 nn 级台阶有 f(n)f(n) 种跳法。在所有跳法中,青蛙的最后一步只有两种情况: 跳上 1级或 2级台阶。 当为 1级台阶: 剩 n-1个台阶,此情况共有 f(n-1)种跳法; 当为 2级台阶: 剩 n-2个台阶,此情况共有 f(n-2)种跳法。 f(n)f(n) 为以上两种情况之和,即 f(n)=f(n-1)+f(n-2),以上递推性质为斐波那契数列。本题可转化为原创 2021-09-26 16:31:40 · 50 阅读 · 0 评论 -
(剑指offer)对称的二叉树
对称的二叉树 题目描述:请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: bool isSymmetric(TreeNode* root) { //如果是空树 if (!root) { return true; } return Helper(root->left, root->right); } /原创 2021-09-26 16:10:13 · 55 阅读 · 0 评论 -
(剑指offer)树的镜像
树的镜像 题目描述:请完成一个函数,输入一个二叉树,该函数输出它的镜像。 输入例如: 镜像输出: 思路:我们从根节点开始,递归地对树进行遍历,并从叶子节点先开始翻转得到镜像。如果当前遍历到的节点root 的左右两棵子树都已经翻转得到镜像,那么我们只需要交换两棵子树的位置,即可得到以 root 为根节点的整棵子树的镜像。 代码如下: TreeNode* mirrorTree(TreeNode* root) { if (root == nullptr) { return nullptr; } Tr原创 2021-09-26 15:26:15 · 55 阅读 · 0 评论 -
(剑指offer)树的子结构
树的子结构 题目描述:输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值。 例如: 给定的树A: 给定的树B: 返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。 思路:若树 B 是树 A 的子结构,则子结构的根节点可能为树 AA 的任意一个节点。因此,判断树 B是否是树 A 的子结构,需完成以下两步工作: 1.先序遍历树 A中的每个节点 ;(对应函数 isSubStructure(A, B)) 2.判原创 2021-09-26 15:00:38 · 56 阅读 · 0 评论 -
(剑指 Offer)旋转数组的最小数字
旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。 思想:找到第一个变小的元素,如果找不到就是第一个。 int minArray(vector<int>& numbers) { int tmp=numbers[0]; for(int i=0;i<numbers.原创 2021-09-23 19:14:35 · 52 阅读 · 0 评论 -
(剑指offer)第一个只出现一次的字符
第一个只出现一次的字符 题目描述:在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 思想:我们可以对字符串进行两次遍历。 在第一次遍历时,我们使用哈希映射统计出字符串中每个字符出现的次数。在第二次遍历时,我们只要遍历到了一个只出现一次的字符,那么就返回该字符,否则在遍历结束后返回空格。 char firstUniqChar(string s) { unordered_map<int, int> frequency; for (原创 2021-09-23 19:06:58 · 66 阅读 · 0 评论 -
(剑指offer)0~n-1中缺失的数字
0~n-1中缺失的数字 题目描写:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。 思想:遍历数组即可。 int missingNumber(vector<int>& nums) { for(int i=0;i<nums.size();++i) { if(nums[i]!=i) {原创 2021-09-22 22:40:21 · 51 阅读 · 0 评论 -
(剑指offer)在排序数组中查找数字 I
在排序数组中查找数字 I 题目描述:统计一个数字在排序数组中出现的次数。 思想:遍历数组,利用tmp记录与target相等的数组,记录一次tmp+1; int search(vector<int>& nums, int target) { int i=0; int tmp=0; for(;i<nums.size();++i) { if(nums[i]==target) {原创 2021-09-22 22:29:18 · 54 阅读 · 0 评论 -
(剑指offer)数组中重复的数字
数组中重复的数字 题目描述:找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 思想:在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内 。 此说明含义:数组元素的 索引 和 值 是 一对多 的关系。因此,可遍历数组并通过交换操作,使元素的 索引 与 值 一一对应(即 nums[i] = inums[i]=i )。因而,就原创 2021-09-22 21:33:42 · 101 阅读 · 0 评论 -
(剑指offer)左旋转字符串
左旋转字符串 题目描述:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。 思想:使用substr (俗称:字符截取函数) 函数格式 : 格式1: substr(string string, int a, int b); 格式2:substr(string string, int a) ; 将字符串倍增成为两个同样的字符串拼接的长字符串然后想旋转原创 2021-09-21 17:08:16 · 46 阅读 · 0 评论 -
(力扣)反转链表
反转链表 题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 方法1:利用栈来实现 ListNode* reverseList(ListNode* head) { stack<int> st; ListNode* p = head; while (p != nullptr) { st.push(p->val); p = p->next; } p = head; while (p != nullptr) { p->val原创 2021-09-20 18:02:34 · 94 阅读 · 0 评论 -
从尾打印链表
从尾打印链表 题目描述:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 思路:栈的特点是后进先出,即最后压入栈的元素最先弹出。考虑到栈的这一特点,使用栈将链表元素顺序倒置。从链表的头节点开始,依次将每个节点压入栈内,然后依次弹出栈内的元素并存储到数组中。 非递归 class Solution { public: vector<int> reversePrint(ListNode* head) { if (!head) return {}; stack&l原创 2021-09-20 16:10:13 · 61 阅读 · 0 评论 -
字符串空格替换
字符串空格替换 请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 思路:我们从后往前开始替换,首先遍历一遍字符串,统计出空格的个数,并由此能够计算出替换之后的字符串的长度。 举个例子: 每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。以"We are happy"为例,“We are happy"这个字符串的长度为14(包括结尾符号”\n"),里面有两个空格,因此替原创 2021-09-19 16:03:37 · 355 阅读 · 0 评论 -
三个多线程的输出
多线程使用:有三个线程,要使其输出是ABCABCABC. #include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; std::mutex mtx; std::condition_variable cv; int isReady=0;//如果isReady为0则输出A,1则是B,2则是C void print原创 2021-06-05 13:11:47 · 80 阅读 · 0 评论 -
静态成员函数的特点
静态成员函数特点: 子对象与父对象共享了父对象所产生的静态成员。从下面的代码中可以看出子对象和父对象共享了一个num. 声明和定义的区别:声明不分配存储空间,而定义需要分配存储空间。 #include <iostream> using namespace std; //static class Object { private: static int num;//声明 int value; public: Object(int x=0) :value(x) {cout<<"Ob原创 2021-03-10 15:08:12 · 409 阅读 · 0 评论