Leetcode 297. 二叉树的序列化与反序列化(DAY 23)(Hard细节挺多的 需要调试一会 含题解)


原题题目


在这里插入图片描述


代码实现(首刷绝大部分自解)


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/** Encodes a tree to a single string. */
char* serialize(struct TreeNode* root){

//基本思路 层序遍历
if(!root)
        return NULL;
    char* tree = (char*)malloc(sizeof(char) * 100000);
    
    //这里的charpos是记录字符串当前到什么位置了
    int size = 0,rear = -1,top = -1,charpos = 0;
    struct TreeNode* queue[50000],*pos = root;
    queue[++rear] = pos;
    while(rear != top)
    {
        size = rear - top; 
        while(size--)
        {
            pos = queue[++top];
            if(!pos)
                charpos += sprintf(tree+charpos,",%s","null");
            else
            {
                if(!top)
                    charpos += sprintf(tree+charpos,"%d",pos->val);
                else
                    charpos += sprintf(tree+charpos,",%d",pos->val);
                    
				//当存在时 则导入其节点 不存在时 则放入NULL 方便检测
                if(pos->left) queue[++rear] = pos->left;
                else queue[++rear] = NULL;
                if(pos->right) queue[++rear] = pos->right;
                else queue[++rear] = NULL;
            }
        }
        //当只存在空结点时 则退出循坏
        if(rear - top == nullnumbers)
            break;
    }
    return tree;
}

/** Decodes your encoded data to tree. */
struct TreeNode* deserialize(char* data) {
if(!data)
        return NULL;
        
    //这里是设定最小值
    const int MIN = -99999;
    int numpos = 0,charpos = 0,num[50000],number,tempnumpos = 0,nextlevel;
    struct TreeNode* stack[50000],*realroot,*root;
    bool flag;//flag的作用是检测是否为负数 因为负数占两个格子

	//下面的while主要将有效数字提取出来 变成数组
    while(charpos < strlen(data))
    {
        flag = false;
        if(data[charpos] == ',')
            charpos++;
        number = 0;
        
        //当出现负数时
        if(data[charpos] == '-')
        {
            flag = true;
            charpos++;
        }
        if(data[charpos] >= '0' && data[charpos] <= '9')
        {
            while(data[charpos] >= '0' && data[charpos] <='9')
                number = number*10 + data[charpos++] - '0';
            if(!flag)
                num[numpos++] = number;
            else
                num[numpos++] = -number;
        }
        else
        {
            num[numpos++] = MIN;
            charpos += 4;
        }
    }

	//创建根节点
    realroot = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    realroot->val = num[tempnumpos];
    realroot->left = realroot->right = NULL;
    stack[tempnumpos] = realroot;

	//nextlevel的作用是 确定左右节点的在数组中的位置
    nextlevel = tempnumpos+1;

    while(tempnumpos < numpos)
    {
        if(num[tempnumpos] != MIN)
        {
            if(nextlevel < numpos && num[nextlevel] != MIN)
            {
                root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
                root->val = num[nextlevel];
                root->right = root->left = NULL;
                stack[tempnumpos]->left = root;
                stack[nextlevel] = root;
            }
            else
                stack[tempnumpos]->left = NULL;
            //向下移动位置
            nextlevel++;
            if(nextlevel < numpos && num[nextlevel] != MIN)
            {
                root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
                root->val = num[nextlevel];
                root->left = root->right = NULL;
                stack[tempnumpos]->right = root;
                stack[nextlevel] = root;
            }
            else
                stack[tempnumpos]->right = NULL;
            //向下移动位置
            nextlevel++;
        }
        tempnumpos++;
    } while(tempnumpos < numpos);
    return realroot;
}
// Your functions will be called as such:
// char* data = serialize(root);
// deserialize(data);

代码实现(二刷 DAY 167 C++ 双百)


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string ret;
        vector<TreeNode*> next,now;
        if(root)
        {
            now.emplace_back(root);
            ret += to_string(root->val);
            ret += ',';
        }
        while(now.size())
        {
            next.clear();
            for(const auto& ptr:now)
            {
                if(ptr->left)
                {
                    next.emplace_back(ptr->left);
                    ret += to_string(ptr->left->val);
                }
                else    ret.push_back('_');
                ret.push_back(',');
                if(ptr->right)
                {
                    next.emplace_back(ptr->right);
                    ret += to_string(ptr->right->val);
                }
                else    ret.push_back('_');
                ret.push_back(',');
            }
            now = next;
        }
        return ret;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data)
    {
        vector<int> num;
        string s;
        vector<TreeNode*> now,next;
        TreeNode* ret = nullptr;
        int pos = 0;
        for(const auto& chr:data)
        {
            if(chr == ',')
            {
                if(s.size())    num.emplace_back(stoi(s));
                s.clear();
            }
            else if(chr == '_')
                num.emplace_back(INT_MIN);
            else s.push_back(chr);
        }    

        if(data.empty())    return nullptr;
        ret = new TreeNode(num[0]);
        ++pos;
        now.emplace_back(ret);
        while(now.size())
        {
            next.clear();
            for(const auto& ptr:now)
            {
                if(num[pos] != INT_MIN)
                {
                    ptr->left = new TreeNode(num[pos]);
                    next.emplace_back(ptr->left);
                }
                if(num[pos+1] != INT_MIN)
                {
                    ptr->right = new TreeNode(num[pos+1]);
                    next.emplace_back(ptr->right);
                }
                pos += 2;
            }
            now = next;
        }
        return ret;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

代码实现(三刷自解 细节很多 需要多做 DAY 258 C++)


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string ret;
        queue<TreeNode*> queue;
        queue.emplace(root);

        while(!queue.empty())
        {
            int size = queue.size();
            for(int i = 0;i < size;++i)
            {
                auto root = queue.front();
                queue.pop();

                if(root)
                {
                    ret += to_string(root->val);
                    queue.emplace(root ? root->left : nullptr);
                    queue.emplace(root ? root->right : nullptr);
                }   
                else    ret += "_";
                ret += ',';
            }
        }

        return ret;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data)
    {
        string tmp;
        vector<int> v;
        for(const auto& chr:data)
        {
            if(chr == ',')
            {
                if(tmp.size())  v.emplace_back(stoi(tmp));
                tmp.clear();
                continue;
            }
            if(chr == '_')     v.emplace_back(INT_MAX);
            else               tmp += chr; 
        }

        int pos = 0,v_size = v.size();
        TreeNode* root = v[pos] == INT_MAX ? nullptr : new TreeNode(v[pos]);
        ++pos;
        queue<TreeNode*> queue;
        if(root)    queue.emplace(root);

        while(queue.size())
        {
            int size = queue.size();
            for(int i = 0;i < size;++i)
            {
                TreeNode* pre = queue.front();
                queue.pop();

                if(pre)
                {
                    pre->left =  (v[pos] == INT_MAX ? nullptr : new TreeNode(v[pos]));
                    pre->right = (v[pos + 1] == INT_MAX ? nullptr : new TreeNode(v[pos + 1]));
                    pos += 2;
                }

                if(pre->left)    queue.emplace(pre->left); 
                if(pre->right)   queue.emplace(pre->right);
            }
        }

        return root;
    }
};


代码实现(四刷自解 DAY 299 C++)


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
 public:
  string serialize(TreeNode* root) {
    deque<TreeNode*> deque;
    deque.emplace_back(root);
    string ret;
    bool nextlevel = true;

    while (!deque.empty() && nextlevel) {
      int size = deque.size();
      nextlevel = false;
      for (int i = 0; i < size; ++i) {
        TreeNode* ptr = deque.front();
        deque.pop_front();
        
        if (!ptr) {
          ret += "_,";
          continue;
        } 

        ret += to_string(ptr->val);
        ret += ',';
        deque.emplace_back(ptr->left);
        deque.emplace_back(ptr->right);
        if (ptr->left || ptr->right) {
          nextlevel = true;
        }
      }
    }

    return ret;
  }

  int GetNextNum(const string& data, int& index) {
    if (index >= data.size()) return INT_MIN;
    if (data[index] == '_') {
      index += 2;
      return INT_MIN;
    }

    int num = 0;
    bool neg = false;
    if (data[index] == '-') {
      neg = true;
      ++index;
    } 
    while (index < data.size() && data[index++] != ',') {
      num *= 10;
      num += (data[index - 1] - '0');
    }
    if (neg) num = -num;
    return num;
  }

  // Decodes your encoded data to tree.
  TreeNode* deserialize(string data) {
    if (data.empty() || data[0] == '_') return nullptr;

    int index = 0;
    int num = GetNextNum(data, index);
    TreeNode* ret = new TreeNode(num);
    deque<TreeNode*> deque;
    deque.emplace_back(ret);

    while (index < data.size()) {
      int size = deque.size();
      for (int i = 0; i < size; ++i) {
        TreeNode* prev = deque.front();
        deque.pop_front();
        int leftnum = GetNextNum(data, index);
        int rightnum = GetNextNum(data, index);

        TreeNode* left = leftnum != INT_MIN ? new TreeNode(leftnum) : nullptr;
        TreeNode* right = rightnum != INT_MIN ? new TreeNode(rightnum) : nullptr;
        prev->left = left;
        prev->right = right;
        if (left) deque.emplace_back(left);
        if (right) deque.emplace_back(right);
      }
    }
    return ret;
  }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

代码实现(五刷自解 DAY 11 Golang)


/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
type Codec struct { 
}

func Constructor() Codec {
  return Codec{}
}

// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
  s := &strings.Builder{}
  if root == nil {
    s.WriteString("_,")
    return s.String()
  }

  deq := []*TreeNode{}
  deq = append(deq, root)
  
  for len(deq) != 0 {
    size := len(deq)
    for i := 0; i < size; i++ {
      ptr := deq[i]
      if ptr != nil {
        s.WriteString(strconv.Itoa(ptr.Val))
      } else {
        s.WriteByte('.')
      }
      s.WriteByte(',')
      if ptr != nil {
        deq = append(deq, ptr.Left)
        deq = append(deq, ptr.Right)
      }
    }
    deq = deq[size:]
  }
  return s.String()
}

// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {    
    if len(data) == 0 || data[0] == '_' {
      return nil
    }

    pos, nextpos := 0, 0
    for ; nextpos < len(data) && data[nextpos] != ','; nextpos++ {
    }
    var ret *TreeNode = nil
    if val, err := strconv.Atoi(data[pos:nextpos]); err == nil {
      ret = &TreeNode{Val : val}
    }
    pos, nextpos = nextpos + 1, nextpos + 1

    deq := []*TreeNode{}
    deq = append(deq, ret)
    
    for len(deq) != 0 {
      size := len(deq)
      judge := false
      for i := 0; i < size; i++ {
        ptr := deq[i]
        var left , right *TreeNode = nil, nil
        
        for ; nextpos < len(data) && data[nextpos] != ','; nextpos++ {
        }
        if val, err := strconv.Atoi(data[pos:nextpos]); err == nil {
          left = &TreeNode{Val : val}
          ptr.Left, deq = left, append(deq, left)
          judge = true
        }
        pos, nextpos = nextpos + 1, nextpos + 1

        for ; nextpos < len(data) && data[nextpos] != ','; nextpos++ {
        }
        if val, err := strconv.Atoi(data[pos:nextpos]); err == nil {
          right = &TreeNode{Val : val}
          ptr.Right, deq = right, append(deq, right)
          judge = true
        }
        pos, nextpos = nextpos + 1, nextpos + 1
      }
      deq = deq[size:]
      if judge == false {
        break
      }
    }
    return ret
}


/**
 * Your Codec object will be instantiated and called as such:
 * ser := Constructor();
 * deser := Constructor();
 * data := ser.serialize(root);
 * ans := deser.deserialize(data);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love 6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值