C++
秦枫-_-
慵懒的程序猿
展开
-
绝对差值和
class Solution { final int mod = 1000000007; public int minAbsoluteSumDiff(int[] nums1, int[] nums2) { int []rec=new int[nums1.length]; System.arraycopy(nums1,0,rec,0,nums1.length); Arrays.sort(rec); int maxn=0,sum=0; for.原创 2021-07-15 00:09:06 · 570 阅读 · 1 评论 -
与数组中元素的最大异或值(字典树)(小于等于某元素的最大异或值)
class Solution { class Tree{ Tree []son=new Tree[2]; } Tree root=new Tree(); void establish(int x){ Tree roo1=root; for(int i=30;i>=0;i--){ int t=x>>i&1; if(roo1.son[t]==null)roo1.son[t]=new.原创 2021-05-23 20:33:53 · 103 阅读 · 3 评论 -
数学博弈游戏
因为s=0,那么一开始爱丽丝就赢了 与假设矛盾了class Solution { public boolean xorGame(int[] nums) { int sum=0; for(int i=0;i<nums.length;i++){ sum^=nums[i]; } return sum==0||nums.length%2==0; }}原创 2021-05-22 10:45:25 · 341 阅读 · 2 评论 -
数组元素拼接成最小值
证明原理过程参考 [link](https://blog.csdn.net/qq_41884662/article/details/115617302)java版本class Solution { public String minNumber(int[] nums) { Integer []num=new Integer[nums.length]; for(int i=0;i<nums.length;i++){ num[i]=nums[i]; .原创 2021-05-10 12:42:56 · 252 阅读 · 2 评论 -
打印二叉树中和为目标值的路径
class Solution { List<List<Integer>> res=new ArrayList<>(); List<Integer> path=new ArrayList<>(); public List<List<Integer>> pathSum(TreeNode root, int target) { int count=0; dfs(root,targe.原创 2021-05-09 12:25:33 · 160 阅读 · 2 评论 -
母亲节做个花----制作 m 束花所需的最少天数
class Solution { public int minDays(int[] bloomDay, int m, int k) { int nums=m*k; if(bloomDay.length<nums)return -1; int low=1,high=Arrays.stream(bloomDay).max().getAsInt(); while(low<high){ int mid=(low+high)/..原创 2021-05-09 11:18:43 · 99 阅读 · 1 评论 -
二分法+回溯+剪枝解决工人完成所有工作最短时间问题
class Solution { public int minimumTimeRequired(int[] jobs, int k) { Arrays.sort(jobs); Collections.reverse(Arrays.asList(jobs)); int low=jobs[0],high=Arrays.stream(jobs).sum(); while(low<high){ int mid=(low+high)/2;...原创 2021-05-09 00:04:21 · 175 阅读 · 4 评论 -
回溯法解决电话号码组合(哈希表和桶)
Java哈希表class Solution { Map<String, String[]> map = new HashMap<>(){{ put("2", new String[]{"a", "b", "c"}); put("3", new String[]{"d", "e", "f"}); put("4", new String[]{"g", "h", "i"}); put("5", new Strin..原创 2021-05-07 17:22:23 · 134 阅读 · 1 评论 -
验证二叉搜索树的后序遍历序列
class Solution { public boolean verifyPostorder(int[] postorder) { return dfs(postorder,0,postorder.length-1); } public boolean dfs(int []postorder,int start,int root){ if(start>=root){ return true; } ...原创 2021-05-07 17:17:37 · 151 阅读 · 2 评论 -
利用数学方法解决数组异或操作
题目用模拟的方法很简单但是数据范围超出到 10^8 大概率会发生 TLE。注:e = n & start & 1;& 1是为了高位全部清零保持最低位数据sumXor(s - 1) ^ sumXor(s + n - 1);是利用了异或的自反性质:前s-1项自身与自身异或结果为0,再利用与0异或等于自身得出s和s+n-1之间的项的异或结果class Solution { public int xorOperation(int n, int start) { .原创 2021-05-07 14:01:48 · 101 阅读 · 1 评论 -
打家劫舍iv----删除并获得点数问题
class Solution { public int deleteAndEarn(int[] nums) { int maxvalue=0; for(int ch:nums){ maxvalue=Math.max(ch,maxvalue); } int []all=new int[maxvalue+1]; for(int ch:nums){ all[ch]+=ch; } return delete(all)..原创 2021-05-06 21:44:40 · 227 阅读 · 1 评论 -
从上到下打印二叉树(之字形打印二叉树)(层序遍历+标志位)
用一个floor标志位表示当前是偶数层还是奇数层,是偶数层就反转一下临时列表Collections.reverse(tmp); 然后res再add(new LinkedList(tmp));,是奇数层直接放入即可。class Solution { public List<List<Integer>> levelOrder(TreeNode root) { Queue<TreeNode> q=new LinkedList<>(); i.原创 2021-04-28 00:21:19 · 138 阅读 · 1 评论 -
验证栈的压入、弹出序列(辅助栈)
class Solution { public boolean validateStackSequences(int[] pushed, int[] popped) { Stack<Integer> stk1=new Stack<>(); int l=0,r=0; for(int i=0;i<pushed.length;i++){ stk1.push(pushed[i]); while(!stk...原创 2021-04-27 22:53:48 · 81 阅读 · 1 评论 -
分割数组的子数组和的最大值最小问题(二分法+贪心算法)
以上两个题考察内容一模一样,均是将数组拆分成一定数量的子数组,求子数组和的最大值,并求解这个最大值的底线为多少?实现思路:二分法查找C++版本class Solution {public: int shipWithinDays(vector<int>& weights, int D) { // 确定二分查找左右边界 int left = *max_element(weights.begin(), weights.end()), rig..原创 2021-04-26 23:29:24 · 3397 阅读 · 1 评论 -
回溯法大集合(全排列+子集+目标和=target)(C++和java都有哦)
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合,每个数字可以使用多次class Solution1 {public: vector<vector<int>> res; vector<int> path; vector<vector<int>> combinationSum(vector<int>& c原创 2021-04-25 23:39:00 · 272 阅读 · 1 评论 -
快速幂(设计pow函数)
利用数学里边的快速幂思想:将n化成二进制数,进行位运算,x*=x,实现了x从低位开始依次得到x^ 2,x ^4,x ^8…,同时幂n右移,右移过程中遇到幂当前位有1,那么记录此时的x,实现过程:当 x = 0时:直接返回 0 (避免后续 x = 1 / x )。初始化 res = 1;当 n < 0时:把问题转化至 n≥0 的范围内,即执行 x = 1/x ,n = - n;循环计算:当 n=0 时跳出;当 n&1=1 时:将当前 x 乘入 res (即 res *= x);..原创 2021-04-23 23:02:13 · 179 阅读 · 1 评论 -
剑指offer14---剪绳子求乘积最大值问题
首先根据算术几何均值不等式(n1+n2+n3…+na)/a>=(n1xn2…na)^(1/a),当且仅当n1=n2=…na时后者能取到最大值。因此我们可以得出若想要乘积最大,应该将绳子尽可能等分切割。那么问题来了,我们均等切割绳子,每一段要求多长呢?切成每段为1也是均等分,不过这样显然是不行的。那么到底怎么求每段的长度最优呢?我们假设分割a段,每段长度为x,则总长n=ax ,x^ a = x ^ (n/x) =( x ^(1/x)) ^n, 即转化为求x ^(1/x)的最大值。.原创 2021-04-23 17:09:20 · 310 阅读 · 1 评论 -
二维矩阵中数据查找(线性查找法O(M+N))
java实现:具体思路:从二维数组的右上角开始查找。如果当前元素的值等于目标值,则返回 true。如果当前元素大于目标值,则向左移。如果当前元素小于目标值,则向下移。我们来这种方法不会错过目标值。如果当前元素大于目标值,说明当前元素的下边的所有元素都一定大于目标值,因此往下查找不可能找到目标值,往左查找可能找到目标值。如果当前元素小于目标值,说明当前元素的左边的所有元素都一定小于目标值,因此往左查找不可能找到目标值,往下查找可能找到目标值。选左上角,往右走和往下走都增大,不能选选右下角,往上.原创 2021-04-22 20:49:43 · 649 阅读 · 1 评论 -
二维前缀和(矩形区域不超过 K 的最大数值和)
如题:我们最直接的思路就是扫描矩阵,从左上角开始,依次从上到下从左到右去扫描查找是否有符合的区域。C++实现:class Solution {public: int maxSumSubmatrix(vector<vector<int>>& matrix, int k) { int m=matrix.size(),n=matrix[0].size(); int res=INT_MIN; for(int up=0;up<m;up++.原创 2021-04-22 15:30:30 · 101 阅读 · 1 评论 -
连续子数组的最大和(动态规划时间复杂度o(n))
本题直接用原数组当做动态规划数组dp,以实现o(1)空间复杂度:JAVA:class Solution { public int maxSubArray(int[] nums) { int res=nums[0]; for(int i=1;i<nums.length;i++){ nums[i]=nums[i-1]<=0?nums[i]:(nums[i]+nums[i-1]); res=Math.max(nums[i],res...原创 2021-04-21 20:40:51 · 275 阅读 · 1 评论 -
两个有序链表合并成一个有序链表(递归+非递归方式)
C++实现非递归class Solution {public: inline ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode *pre=new ListNode(0); ListNode *cur=pre; while(l1!=NULL&&l2!=NULL){ if(l1->val<=l2->val){原创 2021-04-21 19:29:05 · 174 阅读 · 1 评论 -
解码问题(c++和java实现)
遇到求放回方案总数问题–基本上是动态规划:C++实现class Solution {public: int numDecodings(string s) { vector<int> dp(s.size()+1); dp[0]=1; for(int i=1;i<=s.size();i++){ if(s[i-1]!='0')dp[i]=dp[i-1]; if(i>1.原创 2021-04-21 12:19:54 · 82 阅读 · 1 评论 -
数组中数字出现的次数(位运算)
要求必须是O(1)空间复杂度,那么必然不能使用哈希表或者桶这样的集合:只能考虑用位运算解决:看代码之前我们一定要明白异或运算的几个性质:a^ b ^ c = a ^ c ^b,a ^ b=b ^ a,即满足交换律和结合律,a ^ a=0,a ^ 0=a;那么数组中所有元素异或的结果就是那两个只出现了一次的数异或的结果,接着只需要考虑将这个两个数分开即可:那么我们需要明白的是这个结果产生的二进制数是异或的结果,就意味着从右往左数结果rec出现的第一个1就代表了两个数从右往左在这个位置不一样,一个为0.原创 2021-04-19 23:19:19 · 206 阅读 · 2 评论 -
数组中数字出现的次数(用状态机解决)(java实现)
画出真值表:class Solution { public int singleNumber(int[] nums) { int ones = 0, twos = 0; for(int num : nums){ ones = ones ^ num & ~twos; twos = twos ^ num & ~ones; } return ones; }}...原创 2021-04-19 20:38:34 · 155 阅读 · 1 评论 -
C++链表排序(归并法+快速排序)
我们可以试用归并排序解决:对链表归并排序的过程如下。找到链表的中点,以中点为分界,将链表拆分成两个子链表。寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。对两个子链表分别排序。将两个排序后的子链表合并,得到完整的排序后的链表上述过程可以通过递归实现。递归的终止条件是链表的节点个数小于或等于 1,即当链表为空或者链表只包含 1 个节点时,不需要对链表进行拆分和排序。class Solution {.原创 2021-04-18 22:20:14 · 6396 阅读 · 6 评论 -
C++滑动窗口+有序序列解决重复元素or利用桶优化解决
首先放上滑动窗口解决,原理比较简单:对于序列中每一个元素 x 左侧的至多 k个元素,如果这 k 个元素中存在一个元素落在区间 [x - t, x + t]中,我们就找到了一对符合条件的元素。注意到对于两个相邻的元素,它们各自的左侧的 k 个元素中有 k - 1个是重合的。于是我们可以使用滑动窗口的思路,维护一个大小为 k的滑动窗口,每次遍历到元素 x 时,滑动窗口中包含元素 x 前面的最多 k 个元素,我们检查窗口中是否存在元素落在区间 [x - t, x + t]中即可。class Solution.原创 2021-04-17 11:34:25 · 165 阅读 · 3 评论 -
C++二叉树和二叉搜索树的公共祖先查找(后序遍历)
当我们用递归去做这个题时不要被题目误导,应该要明确一点这个函数的功能有三个:给定两个节点 p 和 q如果 p 和 q 都存在,则返回它们的公共祖先;如果只存在一个,则返回存在的一个;如果 p 和 q 都不存在,则返回NULL本题说给定的两个节点都存在,那自然还是能用上面的函数来解决具体思路:(1) 如果当前结点 root 等于 NULL,则直接返回 NULL(2) 如果 root 等于 p 或者 q ,那这棵树一定返回 p 或者 q(3) 然后递归左右子树,因为是递归,使用函数后可认为左.原创 2021-04-16 18:01:44 · 453 阅读 · 1 评论 -
C++扰乱字符串
如题:我们可以采用动态规划解决问题:上面定义中k对应代码中的len,w对应了代码中的k,因为代码比较长,换了变量定义方便我们看懂class Solution {public: bool isScramble(string s1, string s2) { int n = s1.size(); int m = s2.size(); // 如果长度不相等,则必然不相等 if (n != m) { .原创 2021-04-16 14:09:00 · 486 阅读 · 1 评论 -
C++跳跃游戏之能否跳到某个位置(二)(DFS+BFS)
解题思路DFS: 从起点开始用隐形递归栈深度优先搜索并且标记已经访问过的节点,如果任何一条路径遇到0就返回true,否则如果所有路径都没有0,返回false。BFS: 从起点开始用队列宽度优先搜索(出度为2, 即cur + arr[cur], cur - arr[cur])并且标记已经访问过的节点,如果任何一条路径遇到0就返回true,否则如果所有路径都没有0,返回false。代码class Solution {//跳跃游戏3 vector<int> map;public:.原创 2021-04-15 23:39:08 · 166 阅读 · 1 评论 -
C++跳跃游戏之跳到某个位置所需最少次数(贪心算法)
实现思路可以用动态规划思想:以示例为例:设定一个数组表示跳到某个位置所需最少次数,初始位置能跳跃的最大距离是2,那么是不是从初始位置0到1-2区间跳跃任意位置都只需一次就搞定,也就是dp[0]+1,那么1-2区间为起点跳跃时所能到达的最大位置是4,意味着跳到位置3-4区间所需最少次数等于前面区间最少次数+1即可:列出动态方程:当前位置所在区间内所有位置所需最少次数=前一区间所需最少次数+1;class Solution {public: int jump(vector<int&g.原创 2021-04-15 20:59:05 · 1046 阅读 · 1 评论 -
C++打家劫舍问题
总结成一句话就是:走到一间屋要考虑偷还是不偷?首先考虑最简单的情况。如果只有一间房屋,则偷窃该房屋,可以偷窃到最高总金额。如果只有两间房屋,则由于两间房屋相邻,不能同时偷窃,只能偷窃其中的一间房屋,因此选择其中金额较高的房屋进行偷窃,可以偷窃到最高总金额。如果房屋数量大于两间,应该如何计算能够偷窃到的最高总金额呢?对于第 k~(k>2) 间房屋,有两个选项:1.偷窃第 k 间房屋,那么就不能偷窃第 k-1 间房屋,偷窃总金额为前 k-2 间房屋的最高总金额与第 k 间房屋的金额之和。2. 不.原创 2021-04-15 12:22:17 · 1714 阅读 · 1 评论 -
C++前缀树的实现
先看下前缀树的相关使用范例:Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:指向子节点的指针数组children。对于本题而言,数组长度为 26,即小写英文字母的数量。此时children[0] 对应小写字母a,children[1] 对应小写字母 b,children[25] 对应小写字母 z。布尔字段 isEnd,表示该节点是否为字符串的结尾。插入字符串我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:子节点存在。沿着指针移动到子节点,继原创 2021-04-14 23:02:55 · 297 阅读 · 1 评论 -
C++不用“+,-“运算符号,计算两个整数之和(二进制加法运算)
解题思路:a ^ b可以得到两数相加不进位的加法结果(a & b) << 1可以得到两数相加产生的进位二进制的加法无外乎就以下几种情况,1+1 = 0 (有进位)1+0 = 1 (无进位)0+0 = 0 (无进位)0+1 = 1 (无进位)仔细一看,在不考虑进位的情况下,这个不就是二进制的异或操作嘛。所以,我们就可以把加法分成无进位的异或结果,a^b 与保存的进位相加,循环直到没有进位为止,就可以得到结果了。再分析二进制加法中进位怎么能保存,因为只有 1+1的时.原创 2021-04-13 15:47:49 · 564 阅读 · 1 评论 -
C++二叉搜索树的最小节点距离(中序遍历)
如图 找出二叉搜索树的节点最小差值,二叉搜索树是排序树,所以最小差值必然在根节点和对应的子节点之间,所以简单的中序遍历即可双指针法:class Solution {private:int mindiff=INT_MAX;int pre=-1,cur=-1;public: int minDiffInBST(TreeNode* root) { if(!root) return 0; minDiffInBST(root->left); pre.原创 2021-04-13 13:09:07 · 131 阅读 · 1 评论 -
C++跳跃游戏之能否跳到某个位置
解题思路:1.如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。2.可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。3.如果可以一直跳到最后,就成功了。class Solution {public: bool canJump(vector<int>& nums) { int remote = 0; for (int i = 0; i < nums.siz.原创 2021-04-12 22:35:37 · 1172 阅读 · 2 评论 -
C++数组中元素组合出最大值
如题:这可以算是一个算法类class Solution {public: string largestNumber(vector<int>& nums) { string res; sort(nums.begin(), nums.end(), [](const int& x, const int& y) {//自定义一个排序序列方式 long long sx = 10, sy = 10; .原创 2021-04-12 11:49:12 · 1739 阅读 · 3 评论 -
C++动态规划之不同路径总数的游戏
方法一:动态规划思路与算法我们用 f(i, j)表示从左上角走到 (i, j) 的路径数量,其中 i 和 j 的范围分别是 [0, m)和 [0, n)。由于我们每一步只能从向下或者向右移动一步,因此要想走到 (i, j),如果向下走一步,那么会从 (i-1, j) 走过来;如果向右走一步,那么会从 (i, j-1)走过来。因此我们可以写出动态规划转移方程:f(i, j) = f(i-1, j) + f(i, j-1)class Solution {public: int uniqueP.原创 2021-04-11 21:36:37 · 261 阅读 · 1 评论 -
C++关于丑数(判断丑数+查找第n个丑数)
首先看关于丑数的定义:丑数: 就是只包含质因数 2、3 和5 的正整数。换言之:就是%2,或%3,%5==0;一、那么判断丑数的方法就很简单:递归法+迭代法class Solution {public: bool isUgly(int n) {//递归法 if (n == 1)return true; if (!n)return false; if (n % 2 == 0) return isUgly(n / 2); if原创 2021-04-10 13:49:38 · 2627 阅读 · 3 评论 -
C++判断链表有无环(有则给出位置)双指针或哈希表
如图例子:有环的话则会返回节点位置一、双指针法:1.先判断是否存在环2.当第一次快慢指针相遇时,说明存在环,此时相遇点在圆内,此时慢指针走过的距离是x+y,快指针走过的距离是x+y+z+y,因为快指针走过的距离是慢指针的2倍,所以得到等式2(x+y)=x+y+z+y,所以x = z3.接下来,令res = head,让res和slow同时再走一段距离为x的路程,二者就在环入口相遇为何慢指针第一圈走不完一定会和快指针相遇?首先,第一步,快指针先进入环第二步:当慢指针刚到达环的入口时,快.原创 2021-04-09 23:34:27 · 379 阅读 · 1 评论 -
C++构建LRU缓存机制(实现方法:哈希表+双端队列或循环链表)
LRU算法:是大部分操作系统为最大化页面命中率而广泛采用的一种页面置换算法。该算法的思路是,发生缺页中断时,选择未使用时间最长的页面置换出去。 [1] 从程序运行的原理来看,最近最少使用算法是比较接近理想的一种页面置换算法,这种算法既充分利用了内存中页面调用的历史信息,又正确反映了程序的局部问题。要实现LRU,就要使用其他数据结构实现上述几个函数:第一种方法:哈希表+双端队列class LRUCache {private: int num;//元素数量 int _capacit.原创 2021-04-08 23:11:32 · 366 阅读 · 1 评论