day28

1.剑指 Offer 37. 序列化二叉树

复制代码
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Codec {
11 public:
12 
13     // Encodes a tree to a single string.
14     string serialize(TreeNode* root) {
15       if(root == nullptr)  return "[]";
16       string res = "[";
17       queue<TreeNode*> q;
18       q.push(root);
19       while(!q.empty()){
20           //int n = q.size();
21           //for(int i = 0;i < n;i ++){
22               auto tmp = q.front();
23               q.pop();
24               if(tmp == nullptr) res += "null,";
25               else{
26                 res += (to_string(tmp -> val) + ",");
27                 q.push(tmp -> left);
28                 q.push(tmp -> right);
29               }                
30           }
31       }
32       res.pop_back();
33       res += "]";
34       return res;
35     }
36 
37     // Decodes your encoded data to tree.
38     TreeNode* deserialize(string data) {
39         if(data == "[]")  return nullptr;
40         vector<string> str;
41         str = split(data.substr(1,data.length() - 2),",");
42         TreeNode* root = new TreeNode(std::stoi(str[0]));
43         queue<TreeNode*> q;
44         q.push(root);
45         int i = 1;
46         while(!q.empty()){
47             auto cur = q.front();
48             q.pop();
49             if(str[i] != "null"){
50                 cur -> left = new TreeNode(std::stoi(str[i]));
51                 q.push(cur -> left);
52             }  
53             i ++;
54             if(str[i] != "null"){
55                 cur -> right = new TreeNode(std::stoi(str[i]));
56                 q.push(cur -> right);
57             }  
58             i ++; 
59         }
60         return root;
61     }
62 
63 private:
64     vector<string> split(string str,string delim){
65         vector<string> res;
66         int len = str.length();
67         int i = 0;
68         while(i < len){
69             int j = i;
70             while(j < len && str[j] != ',')  j ++;
71             res.push_back(str.substr(i,j - i));
72             i = ++ j;
73         }
74         return res;
75     }
76 };
77 
78 // Your Codec object will be instantiated and called as such:
79 // Codec codec;
80 // codec.deserialize(codec.serialize(root));
复制代码

2.剑指 Offer 38. 字符串的排列

 dfs,这种写法就是模板写法了,设一个数组visited来记录哪些元素被使用过了;dfs之前要标记visited[i] = 1,遍历之后恢复现场 visited[i] = 0;达到触发条件就返回

复制代码
 1 class Solution {
 2 public:
 3     vector<string> permutation(string s) {
 4       unordered_map<char,char> map;
 5       int len = s.length();
 6       for(int i = 0;i < len;i ++){
 7         if(map.find(s[i]) != map.end()) continue;
 8         map[s[i]] = s[i];
 9         dfs(s,i,len,1);
10         str.pop_back(); //把第一个元素弹出来
11       }
12       return res;
13     }
14 
15 private:
16     int visited[9];
17     string str;
18     vector<string> res;
19     unordered_map<string,string> resmap;
20     void dfs(string s,int i,int len,int cnt){
21        str += s[i];
22        if(cnt == len){
23           if(resmap.find(str) == resmap.end()){
24               res.push_back(str);
25               resmap[str] = str;
26           }  
27           return;
28        } 
29        visited[i] = 1;
30        for(int j = 0;j < len;j ++){
31           if(visited[j] == 0){
32              dfs(s,j,len,cnt + 1);
33              str.pop_back();
34           } 
35       }
36       visited[i] = 0;
37     }
38 
39 };
复制代码

 大佬简洁代码:

 https://leetcode.cn/leetbook/read/illustration-of-algorithm/50hah3/

 注意开头,n个字符排列有 n * (n - 1) * (n - 2) * ... * 1 种方案

 就是说第一个位置有n个选择,第一个位置有字符后,第二个位置还剩下(n - 1)个选择,第二个位置有字符以后,第三个位置还剩下(n - 2)个选择,依此类推,到最后一个位置只剩一个字符,触发返回条件

 第一个位置选择一个字符后遍历完了所有的可能,这个时候要在剩下的n - 1个字符中选一个放在第一个位置,依此类推,直到n个字符都在第一个位置开始,遍历过所有可能(这个时候,就要注意剪枝!如果n个字符中有重复的遍历一个就行了,否则就会重复)

 下面代码是通过交换两个字符的位置来达到上面过程的效果

复制代码
 1 class Solution {
 2 public:
 3     vector<string> permutation(string s) {
 4         dfs(s, 0);
 5         return res;
 6     }
 7 private:
 8     vector<string> res;
 9     void dfs(string s, int x) {
10         if(x == s.size() - 1) {
11             res.push_back(s);                       // 添加排列方案
12             return;
13         }
14         set<int> st;
15         for(int i = x; i < s.size(); i++) {
16             if(st.find(s[i]) != st.end()) continue; // 重复,因此剪枝
17             st.insert(s[i]);
18             swap(s[i], s[x]);                       // 交换,将 s[i] 固定在第 x 位
19             dfs(s, x + 1);                          // 开启固定第 x + 1 位字符
20             swap(s[i], s[x]);                       // 恢复交换
21         }
22     }
23 };
复制代码

 

posted @   balabalahhh  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示