leetcode
剑指 Offer 47. 礼物的最大价值
思路:类似数字三角形,dp[i][j]=max(dp[i−1][j],dp[i][j−1])+grid[i][j]
在每次转移中,grid[i][j]grid[i][j] 总共只用了一次,所以可以直接用grid作为dp数组

class Solution { public: int maxValue(vector<vector<int>>& grid) { for(int i=0;i<grid.size();i++) { for(int j=0;j<grid[0].size();j++) { if(i&&j) { grid[i][j]+=max(grid[i][j-1],grid[i-1][j]); } else if(i) { grid[i][j]+=grid[i-1][j]; } else if(j) { grid[i][j]+=grid[i][j-1]; } } } return grid.back().back(); } };
剑指 Offer 32 - II. 从上到下打印二叉树 II
思路:BFS,每一层开一个vector<int>temp,每遍历完一层在队列中加入一个NULL,当队头是NULL则表示一层遍历完,都在temp里面,就将temp加入res,然后再将队列加入NULL
(每一层结束的时候,往queue里塞一个NULL做标记。在queue里读取一个数出来之后,先看看是不是level标识符NULL(因为是BFS,当前level读完,下一个level有哪些要读的也都放在queue里了,可以在queue结尾给加一个新的NULL), 是的话再看看是不是整个树读完了(即queue里没有点了))

class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> res; if(!root) { return res; } queue<TreeNode*> q; q.push(root); q.push(NULL); vector<int> temp; while(q.size()) { auto now=q.front(); q.pop(); if(!now) { if(temp.empty())break; class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> res; if(!root) { return res; } queue<TreeNode*> q; q.push(root); q.push(NULL); vector<int> temp; while(q.size()) { auto now=q.front(); q.pop(); if(!now) { if(temp.empty())break; res.push_back(temp); temp.clear(); q.push(NULL); } else { temp.push_back(now->val); if(now->left)q.push(now->left); if(now->right)q.push(now->right); } } return res; } }; res.push_back(temp); temp.clear(); q.push(NULL); } else { temp.push_back(now->val); if(now->left)q.push(now->left); if(now->right)q.push(now->right); } } return res; } };
1. 两数之和 - 力扣(LeetCode) (leetcode-cn.com)
思路:map映射
C++:

class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { map<int,int> mp; vector<int> res; for(int i=0;i<nums.size();i++) { int x=nums[i]; if(mp.count(target-x)) { res.push_back(i); res.push_back(mp[target-x]); } mp[x]=i; } return res; } };
JAVA:

class Solution { public int[] twoSum(int[] nums, int target) { int[] res=new int[2]; Map<Integer,Integer> mp=new HashMap<>(); for(int i=0;i<nums.length;i++) { int x=nums[i]; int y=target-x; if(mp.containsKey(y)) { return new int[]{i,mp.get(y)}; } mp.put(x,i); } throw new RuntimeException(); } }
3. 无重复字符的最长子串 - 力扣(LeetCode) (leetcode-cn.com)
思路:双指针,i,j两个指针,当i指针大于1以后,j++,直到j指针所在的字符等于1

class Solution { public: int lengthOfLongestSubstring(string s) { map<char,int> mp; int res=0; for(int i=0,j=0;i<s.size();i++) { mp[s[i]]++; while(mp[s[i]]>1) { mp[s[j++]]--; } res=max(res,i-j+1); } return res; } };
5. 最长回文子串 - 力扣(LeetCode) (leetcode-cn.com)
思路: dp[i][j] 表示 s[i] 至 s[j]如果是回文子串则为1, 反之则为0
1. s[i]==s[j] 那么只需要 s[i+1], s[j-1]是回文子串, s[i]至s[j] 就是回文子串:
dp[i][j] = dp[i+1][j-1]
2. s[i]!=s[j]:
dp[i][j] = 0 s[i]至s[j]不是回文子串
根据从边界出发的原理, 注意到边界都是长度为1或2的子串, 每次转移都对子串的长度-1, dp[i][j] = dp[i+1][j-1]
不妨考虑按子串的长度和子串的初始位置进行枚举
第一遍先枚举长度为3的子串的dp值, 然后第二遍枚举长度为4的子串的dp值

class Solution { public: string longestPalindrome(string s) { int n=s.size(); if(s.size()<2) { return s; } int ans=1; int start=0; vector<vector<int>> dp(n,vector<int>(n)); for(int i=0;i<n;i++) { dp[i][i]=1; if(s[i]==s[i+1]&&i<n-1) { ans=2; start=i; dp[i][i+1]=1; } } for(int l=3;l<=n;l++) { for(int i=0;i+l-1<n;i++) { int j=i+l-1; if(s[i]==s[j]&&dp[i+1][j-1]) { dp[i][j]=1; start=i; ans=l; } } } return s.substr(start,ans); } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧