- 博客(67)
- 收藏
- 关注
原创 LeetCode105
重建二叉树分析这道题难道是不难,主要是我一边写一边想事情,然后写完提交就过了。。。。直接在页面上写的,编译也是一次就过了记录一下/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {}
2021-03-03 22:49:24 138 1
原创 LeetCode1438
绝对差不超过限制的最长连续子数组## 分析其实这个题显然是一个滑动窗口的问题,但是有一个问题就是怎么快速的窗口间的极值。其实这个维护一下当前窗口里面的最大最小值就好了,但是也可以简单点,维护一个BST,动态的插入和删除。C++STL里面有很多这样的数据结构,比如set,但是这里的元素可能是有重复的,所以使用多重集合multiset这个数据结构就比较easy了。class Solution {public: int longestSubarray(vector<int>&
2021-02-21 18:41:30 238
原创 LeetCode561
数组拆分 I分析贪心思想class Solution {public: int arrayPairSum(vector<int>& nums) { int ans=0; sort(nums.begin(),nums.end()); for(int i=0;i<nums.size();i+=2){ ans+=nums[i]; } return ans; }};...
2021-02-16 21:29:52 144
原创 LeetCode124
二叉树中的最大路径和分析dfs一下就好class Solution {public: int ans = -2e9; int maxPathSum(TreeNode* root) { getAns(root); return ans; } int getAns(TreeNode* rt) { if (!rt)return 0; int l=getAns(rt->left); int
2021-02-13 19:23:15 140
原创 LeetCode42
接雨水分析对于每一个高度找到左边第一个比它小的,然后计算蓄水量。找到左边第一个比它小的这个操作使用单调栈处理class Solution {public: int trap(vector<int>& height) { stack<int>st; int ans = 0; for (int i(0); i < height.size(); i++) { int last = 0; while (st.size() &&
2021-02-13 18:44:42 116
原创 LeetCode316
去除重复字母分析单调栈+贪心class Solution {public: string removeDuplicateLetters(string s) { map<char, int>mp; map<char, int>inner; for (char c : s) { mp[c]++; inner[c] = 0; } stack<
2021-02-12 21:08:25 96
原创 LeetCode402
移掉K位数字分析维护一个单调递增的单调栈,顺序移除。class Solution {public: string removeKdigits(string num, int k) { stack<char>st; if (!num.size())return "0"; for (int i(0); i < num.size(); i++) { while (k && st.size()
2021-02-12 19:14:43 135
原创 LeetCode322
零钱兑换分析是一个完全背包问题。class Solution {public: int coinChange(vector<int>& coins, int amount) { int dp[10000+100]; memset(dp,0x7f,sizeof(dp)); dp[0]=0; for(int i=0;i<coins.size();i++){ for(int j=co
2021-02-08 21:53:52 116
原创 LeetCode141
环形链表分析快慢指针。class Solution {public: bool hasCycle(ListNode *head) { if(!head||head->next==NULL)return false; ListNode * fast=head->next; ListNode * slow=head; while(fast!=slow){ if(fast==NULL||fast-
2021-02-08 21:21:26 92
原创 LeetCode169
多数元素分析写一种比较巧妙的写法class Solution {public: int majorityElement(vector<int>& nums) { int cur=nums[0]; int cnt=0; for(int c:nums){ if(c==cur)cnt++; else { cnt--;
2021-02-08 21:12:50 88
原创 LeetCode221
最大正方形分析首先说一个暴力解法,首先做一个前缀和然后枚举这个这个正方行的边长。这个解法的复杂度大概是:∑i=1n∑j=1m∑k=1n1k=>mn∗lnn\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{k=1}^{n}\frac{1}{k} => mn*lnni=1∑nj=1∑mk=1∑nk1=>mn∗lnn希望我没有算错。这个复杂度有点拉跨,其实考虑dpdp[i][j]表示已(i,j)为右下角的最大边长,dp[i][j]=min(dp[i−1
2021-02-08 17:20:44 252
原创 LeetCode 31
下一个排列分析首先说一件比较尴尬的事情,就是这个题目确实有面试官问到过我,我开始给出的回答就是直接找到第一逆序的地方交换就好了,没有考虑到其实找到之后应该继续从后往前找到最合适的。其实这是一个贪心的算法,当时面试官还是很棒的,给我了一个例子让我跑一下我就发现了问题,然后补足了这个地方。其实题还是要多刷刷,否则很容易出现思维漏洞。class Solution {public: void nextPermutation(vector<int>& nums) {
2021-02-07 13:59:24 90
原创 LeetCode21
合并两个有序链表分析比较easyclass Solution {public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(!l1&&(!l2))return l1; ListNode* newHead=new ListNode; ListNode* cur=newHead; while(l1!=NULL&&l2!=NULL)
2021-02-06 00:37:56 81
原创 LeetCode206
反转链表分析采用头插法反转,代码看着有点绕。class Solution {public: ListNode* reverseList(ListNode* head) { ListNode * newHead=NULL; while(head!=NULL){ ListNode*curHead=head; head=head->next; curHead->next=newHe
2021-02-06 00:06:43 117
原创 LeetCode46
全排列分析注意一下排列的生成规则,当前的数和所有数互换一下。回溯的时候记得换回来class Solution {public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>>ans; getPerm(nums, ans, 0); return ans; } void ge
2021-02-05 23:51:07 84
原创 LeetCode 279
完全平方数分析一个比较easy的dpclass Solution {public: int numSquares(int n) { // dp[i]表示组成i最小的平方数 dp[i]=min(dp[i],dp[i-j*j]) int dp[10000]; memset(dp, 0x7f, sizeof(dp)); dp[1] = 1; dp[0] = 0; for (int i = 1; i &l
2021-02-05 23:44:13 83
原创 LeetCode78
子集分析二进制压缩class Solution {public: vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>>ans; for (int status = 0; status <(1 << nums.size()); status++) { ans.push_
2021-02-05 17:23:59 91
原创 LeetCode98
验证二叉搜索树## 分析按照中序遍历的规则验证一下就好class Solution {public: long long pre = -1e18; bool isValidBST(TreeNode* root) { if (root == NULL)return true; // 左子树遍历 if (!isValidBST(root->left)) { return false; }
2021-02-04 22:33:35 135
原创 LeetCode152
乘积最大子数组分析和最大子段和差不多,只是这里其实有点小区别就是会有负数的出现,其实我们可以维护两个极端,一个是最大值一个是最小值,然后当nums[i]是负数的时候,就开始使用最小值更新答案,否则使用最大值更新答案.class Solution {public:#define ll long long int maxProduct(vector<int>& nums) { ll ans = -1e18; int curMax = 1,
2021-02-04 16:42:49 103
原创 LeetCode53
最大子序列和分析一个经典的DP,对于每一个考虑两种,第一是把之前的结果加上来,就是连上之前的。那么就是dp[i-1]+nums[i],否则就是从这个重新开始取个最大值。因为答案可能会在这中间产生,所以每次要更新答案class Solution {public: int maxSubArray(vector<int>& nums) { int dp[20000 + 100]; if (!nums.size())return 0;
2021-02-04 15:21:24 168
原创 LeetCode643
子数组最大平均数 I分析其实要求连续就是等于某一段前缀和,把前缀和算一下就好了class Solution {public: double findMaxAverage(vector<int>& nums, int k) { if (!nums.size())return 0; int pre[3000 + 100]; pre[0] = nums[0]; for (int i = 1; i < num
2021-02-04 15:11:53 142
原创 LeetCode480
替换后的最长重复字符分析滑动窗口分析最长连续最值。class Solution {public: int characterReplacement(string s, int k) { map<char, int>mp; int l = 0, r = 0; int ans = 0; while (r < s.size()) { mp[s[r]]++; ans =
2021-02-03 23:08:32 77
原创 LeetCode416
分割等和子集分析其实就是一个背包问题,但是这个背包问题不是求最值,而是求解是都可达。class Solution {public: bool canPartition(vector<int>& nums) { int dp[200 * 100 + 100]; memset(dp, 0, sizeof(dp)); dp[0] = 1; int sum = 0; for (int c : num
2021-02-03 22:30:44 124
原创 LeetCode437
路径总和 III## 其实这个题就是前边的加强版吧,考虑使用每个节点作为叶子节点然后dfs,所以这里就需要两个dfs,第一个是普通的统计dfs,第二个是遍历树哦那个的dfsclass Solution {public: int ans = 0; int pathSum(TreeNode* root, int sum) { if (root == NULL)return 0; dfs2(root, sum); return ans;
2021-02-03 13:15:47 125
原创 LeetCode448
找到所有数组中消失的数字分析其实可能有很多种写法吧,但是时间O(N),空间O(1)还是有一些小小的技巧的,其实就是原地修改数组,数组中的每个元素都对着一个下标。把这个下下标对应的地方标记一下就好了。class Solution {public: vector<int> findDisappearedNumbers(vector<int>& nums) { vector<int>ans; if (!nums.size
2021-02-03 12:30:03 128
原创 LeetCode461
汉明距离这个东西在计算机网络里面有很大的作用,主要用于包的纠错。分析搜先异或一下然后找1class Solution {public: int hammingDistance(int x, int y) { int ans=(x^y); int cnt=0; while(ans!=0){ if(ans&1)cnt++; ans>>=1; }
2021-02-03 00:14:51 106
原创 LeetCode494
目标和分析先写个暴力吧,其实就是在一颗二叉树上找一条根节点到叶子节点和为S的路径。DFS一下就好了,所以这显然也是可以DP的。class Solution {public: int ans = 0; int findTargetSumWays(vector<int>& nums, int S) { if (nums.size() == 0)return 0; dfs(nums, 0, nums[0],S); df
2021-02-03 00:09:17 109
原创 LeetCode543
二叉树的直径分析开始简单的以为其实就是左右最大深度之和,然后发现有点不对劲,其实如果这个树很不平衡,那么这个最大直径极有可能出现在某颗子树上。所以正解其实有很多种写法,可以向像我这样直接无脑的写/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(
2021-02-02 23:48:17 115
原创 LeetCode560
和为K的数组分析其实也比较好想,因为要求的是连续的子数组。所以就是要求某两个前缀和相减=k,其实即使presum[i]-presum[j]=k,可以看作是presum[i]-k=presum[j],所以枚举一下前缀就出来了。class Solution {public: int subarraySum(vector<int>& nums, int k) { map<long long, int >mp; long long s
2021-02-02 22:57:05 114
原创 LeetCode 581
最短无序连续子数组## 分析论读题的重要性,好吧还是改不掉这个毛病。因为要求是连续的,并且整个数组最后是严格递增的,那么就显然可以知道数组最后的位置就是开始排序。然后对比一下就好了。其实这个数组可以分为三部分:有序1+无序+有序2。这个无序的左右端点都可以找到。可以思考一下怎么找。class Solution {public: int findUnsortedSubarray(vector<int>& nums) { vector<int>ol
2021-02-02 21:51:47 98
原创 LeetCode617
合并两个二叉树代码按照树的遍历合并就好了class Solution {public: TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { TreeNode* cur = new TreeNode; if (t1 == NULL)return t2; if (t2 == NULL)return t1; cur->val = t1->val + t2->val;
2021-02-02 21:01:24 83
原创 LeetCode647
回文子串的数量分析首先写个暴力然后闯过去了class Solution {public: bool ispara(string s) { for (int i = 0; i < s.size() / 2; i++) { if (s[i] != s[s.size() - i - 1])return false; } return true; } int countSubstrings(string
2021-02-02 20:01:50 91
原创 LeetCode739
每日温度分析维护一个单调递减的栈,从后往前扫一遍。代码代码在到处特判。。。。class Solution {public: vector<int> dailyTemperatures(vector<int>& T) { const int maxn = 1e5 + 10; int st[maxn]; memset(st, 0, sizeof(st)); int top = -1;
2021-02-02 00:30:26 89
原创 LeetCode 07
题意代码class Solution {public: int reverse(int x) { int falg = x > 0; x = abs(x); long long res = 0; while (x > 0) { res = res * 10 + x % 10; x /= 10; } if (res > (2ll &
2021-01-10 17:16:44 95
原创 LeetCode 5
题意解法首先我提供一个暴力的DP解法。dp[i][j]表示s[i,j]是是不是回文。然后转移取决于dp[i+1][j-1].class Solution { public String longestPalindrome(String s) { boolean [][]dp=new boolean[2000][2000]; String ans=""; for(int len=1;len<=s.length();len++){
2021-01-10 17:00:45 119
原创 leetcode 228
题意解法其实比较简单直接贴代码了 class Solution { public List<String> summaryRanges(int[] nums) { final String interval="->"; List<String>ans=new ArrayList<>(); Arrays.sort(nums); int i=0;
2021-01-10 15:10:19 87
原创 CF 1466C
题目介绍链接。一句话就是改动最少的字符使得这个字符串不出现大于2的回文子串。分析首先介绍一种贪心的写法。我们首先考虑怎么去修改一个字符串。例如bbbb这个字符串:(1)bbbb 首先考虑第一位,没问题。考虑第二位,后面有一个和它一样的,那么我们把它修改掉。修改为多少呢?假设修改为c。这个时候字符串为bcbb(2)考虑第三位其实你发现,这个位置的修改会影响到两个位置,i-1,和i-2.你要保证本次修改不会让s[i-2],s[i-1],s[-2]成为一个回文串。修改为多少呢?这其实是一个大问题,我当时
2021-01-02 16:04:09 204
原创 CF 1462D
题意链接题目的大意就是给一个数组,可以把相邻的数合并到一起,问你最少合并多少次才能把这个数组合并成所有元素都相等。分析首先考虑所有元素都相等是什么情况,因为总和不变,所以最后的情况就是每个数都是总和的因子。所以我们就可以遍历每一个因子,检查是否能够合并成这个因子。因为一个数的因子的数量是有限的,可以理解为常数个。所以这个遍历的复杂度很低,然后考虑怎么检查。从前往后考虑,如果a1正好等于目标,那么跳过考虑a2,如果a1比目标小,那么需要加上a2,如果加上a2还是小,就加上a3,如果加上a3继续小,依次类
2020-12-19 17:10:51 158 1
原创 CF 1462B
CF1462B链接题意就是给你一个字符串,问你至多删一个子串能不能变成2020.分析这个题目其实还是比较简单的,不知道别人怎么做的,我是这样考虑的。考虑这个最后的答案2020从哪里开始,比如头部没有,那答案必然是最后四个字母是2020,如果开始有个2,那么后面三个就得是020,如果开始是202,那么最后一个就要是0,如果开始就是2020,那么后面就不用考虑。就这样判断一下就好了。#include <iostream>using namespace std;int main(){
2020-12-19 16:23:51 163 1
原创 CF1462 C
题目简介链接题目比较简短其实还是很好读懂的,就是给你一个数字找一下最小一个数字数位和等于这个数字并且这个数字还没有重复。分析可以看到数据量很小,所以就没有怎么思考。直接打个表交了。#include <iostream>#include<algorithm>using namespace std;#define ll long long//ll ans=1e18;//void dfs(int vis[],int cur,ll curAns){// if(cur
2020-12-19 15:20:02 207 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人