1. 树结构 与 链表之间的转换关系:
437. 路径总和 III : 二叉树 与 链表之间的思维转换 + 链表解决题目的方法;

1 //二叉树相当于 两条走向的链表,这道题对于链表用前缀和解决; 2 //那么两条走向的链表 处理方法; 3 /** 4 * Definition for a binary tree node. 5 * struct TreeNode { 6 * int val; 7 * TreeNode *left; 8 * TreeNode *right; 9 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 * }; 13 */ 14 class Solution { 15 public: 16 unordered_map<int, int> cnt; 17 int dfs(TreeNode *root, int targetSum, int sum) { 18 if(!root) return 0; 19 sum += root->val; 20 int ans = cnt[sum - targetSum]; 21 cnt[sum] += 1; 22 ans += dfs(root->left, targetSum, sum); 23 ans += dfs(root->right, targetSum, sum); 24 cnt[sum] -= 1; 25 26 return ans; 27 } 28 29 int pathSum(TreeNode* root, int targetSum) { 30 cnt.clear(); 31 cnt[0] = 1; 32 return dfs(root, targetSum, 0); 33 } 34 }; 35 36 //正常递归思路 37 /** 38 * Definition for a binary tree node. 39 * struct TreeNode { 40 * int val; 41 * TreeNode *left; 42 * TreeNode *right; 43 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 44 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 45 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 46 * }; 47 */ 48 class Solution { 49 public: 50 int ans; 51 void dfs(TreeNode *root, int targetSum, bool start) { 52 if(!root) return; 53 54 if(root->val == targetSum) ans += 1; 55 56 if(!start) { 57 dfs(root->left, targetSum, false); 58 dfs(root->right, targetSum, false); 59 } 60 61 dfs(root->left, targetSum - root->val, true); 62 dfs(root->right, targetSum - root->val, true); 63 return; 64 } 65 66 int pathSum(TreeNode* root, int targetSum) { 67 ans = 0; 68 dfs(root, targetSum, false); 69 return ans; 70 } 71 };
2. 数组结构代表的含义可以有很多。
a. 完全二叉树;
b. map:下标 与 数据 之间对应关系;
c. 链表关系:下标为值, 值代表指向的下一个节点;
287. 寻找重复数 : rev0/rev1 利用 上面 b 的想法;rev2 利用上面c的关系;

1 class Solution { 2 public: 3 int findDuplicate(vector<int>& nums) { 4 //rev2 5 //可以把数据当作链表,数组中储存的值是下一个链表节点 6 int s = 0, f = 0; 7 do { 8 s = nums[s]; 9 f = nums[nums[f]]; 10 }while(s != f); //必须先循环起来,因为开始点也是相等的; 11 12 s = 0; 13 while(s != f) { 14 s = nums[s]; 15 f = nums[f]; 16 } 17 18 return s; 19 20 //rev1: 改变了nums, 21 // int temp = nums[0]; 22 // while(1) { 23 // if(temp == nums[temp]) return temp; 24 // int next = nums[temp]; 25 // nums[temp] = temp; 26 // temp = next; 27 // } 28 // return 0; 29 // 30 // rev0: 改变了nums 31 // sort(nums.begin(), nums.end()); 32 // for(int i = 1, I = nums.size(); i < I; ++i) { 33 // if(nums[i] != nums[i - 1]) continue; 34 // return nums[i]; 35 // } 36 // return 0; 37 } 38 };
3. 辗转相除的过程:

1 class Solution { 2 public: 3 int gcd(int a, int b) { 4 if(!b) return a; 5 return gcd(b, a % b); 6 } 7 string gcdOfStrings(string str1, string str2) { 8 if(str1 + str2 != str2 + str1) return ""; 9 int cnt = gcd(str1.size(), str2.size()); 10 return str1.substr(0,cnt); 11 12 } 13 };
str1 + str2 = str2 + str1 ==> str1 中前缀 与 后缀相同 ==> str1 前缀 = str2 前缀, str2 后缀 = str1 后缀;
分类:
算法思路与技巧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)