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. 辗转相除的过程:

  1071. 字符串的最大公因子

 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 后缀;

  

 

posted on 2022-05-22 22:48  学海一扁舟  阅读(26)  评论(0编辑  收藏  举报