zoukankan      html  css  js  c++  java
  • leetcode刷题笔录3

    13.三角形

    • 给出一个“三角形”,找到从底边到顶点的最小路径(即,路径上所有元素加和最小)。路径只能跨越相邻的点。如给出:
           [2],
          [3,4],
         [6,5,7],
        [4,1,8,3]

      那么就返回11,因为最短路径1-5-3-2的和为11。

    • 思路:很简单,与算法导论中一道“国际象棋”棋盘的题很类似。从底边开始生成到每个点的最小路径加和。
    • 实现:
      class Solution {
      public:
          int minimumTotal(vector<vector<int> > &triangle) {
              int n = triangle.size();
              vector<vector<int>> sum(triangle);
              for(int i=n-2; i>=0; i--){
                  for (int j=0; j<=i; j++){
                      sum[i][j] += sum[i+1][j]<sum[i+1][j+1] ? sum[i+1][j] : sum[i+1][j+1];
                  }
              }
              return sum[0][0];
          }
      };

    14.帕斯卡三角形

    • 给出nRows,生成帕斯卡三角形。如给出nRows=5,则返回:
      [
           [1],
          [1,1],
         [1,2,1],
        [1,3,3,1],
       [1,4,6,4,1]
      ]
    • 思路:简单,过。
    • 实现:
      class Solution {
      public:
          vector<vector<int> > generate(int numRows) {
              vector<vector<int>> triangle;
              for (int i=0; i<=numRows-1; i++){
                  vector<int> row;
                  if (i==0){
                      row = vector<int>(1,1);
                  }
                  else{
                      for (int j=0; j<=i; j++){
                          if (j==0)
                          {
                              row.push_back(triangle[i-1][j]);
                          }
                          else if (j==i)
                          {
                              row.push_back(triangle[i-1][j-1]);
                          }
                          else{
                              row.push_back(triangle[i-1][j-1]+triangle[i-1][j]);
                          }
                      }
                  }
                  triangle.push_back(row);
              }
              return triangle;
          }
      };  

    15.帕斯卡三角形2

    • 给出索引值k,返回帕斯卡三角形中的第k行。如给出k=3,则返回[1,3,3,1]。只允许使用O(k)的额外空间。
    • 思路:也很简单,因为计算每一行只需要用到上一行的值,而跟上一行之上没有关系。所以只需要维护三角形中至多两行,空间消耗为O(2k)=O(k)。
    • 实现:
      class Solution {
      public:
          vector<int> getRow(int rowIndex) {
              vector<int> tmp;
              vector<int> current;
              for (int i=0; i<=rowIndex; i++){
                  current = vector<int>();
                  if (i==0){
                      current.push_back(1);
                  }
                  else{
                      for(int j=0; j<=i; j++){
                          if (j==0 || j==i){
                              current.push_back(1);
                          }
                          else{
                              current.push_back(tmp[j-1]+tmp[j]);
                          }
                      }
                  }
                  tmp = current;
              }
              return current;
          }
      };

    16.下一个右节点

    • 给出一个最简单的二叉树,树的节点有一个额外的域next(见代码注释),指向相同深度节点中右边一个节点,如果已经是同一深度最右的节点了,那么next域则为NULL。现在的二叉树中所有节点next域都为NULL,处理该二叉树使得其具有上述性质。在这个问题中,假设二叉树是完整的(所有叶子节点在同一深度)。比如给出:
               1
             /  \
            2    3
           / \  / \
          4  5  6  7

      则返回:

               1 -> NULL
             /  \
            2 -> 3 -> NULL
           / \  / \
          4->5->6->7 -> NULL
    • 思路:正常的进行前序遍历,对每一个节点:
      • 使K的左子结点next域指向K的右子结点
      • 使K的右子结点指向K的next节点的左子节点
      • 注意我们使用的是前序遍历,这说明在处理K节点的左子结点和右子结点时,我们已经处理了K节点的父节点的左子结点和右子结点(这就包括K),K节点的next域已经指向了应该指向的位置。
    • 实现:
      /**
       * Definition for binary tree with next pointer.
       * struct TreeLinkNode {
       *  int val;
       *  TreeLinkNode *left, *right, *next;
       *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
       * };
       */        
      class Solution {
      public:
          void connect(TreeLinkNode *root) {
              if (root == NULL){
                  return;
              }
              if (root->left != NULL && root->right != NULL){
                  root->left->next = root->right;
                  root->right->next = root->next==NULL ? NULL : root->next->left;
              }
              connect(root->left);
              connect(root->right);
          }
      };

    17.下一个右节点2

    • 同上一题,但此时二叉树不再是完整的了。同时,要求仅使用常量规模的额外存储空间。如,给出:
               1
             /  \
            2    3
           / \    \
          4   5    7

      应当返回:

               1 -> NULL
             /  \
            2 -> 3 -> NULL
           / \    \
          4-> 5 -> 7 -> NULL
    • 思路:由于只能使用常量规模的额外空间了,所以不使用递归而使用循环遍历。节点的next域使我们的按行遍历变得很方便(这种广度优先遍历本来是需要队列支持的)。在实现中,按照行遍历二叉树,当处理某个节点的子节点时,该节点所在的行都已经被next指针连接起来了。根据这篇博文的思路:
      • 方法getNext(node)的作用是:返回节点的左节点,如果没有就返回其右节点,如果还没有就返回其next(同一行右侧节点)节点的左节点,其右节点……依此类推。
      • 这个方法有两个作用:
        • 当前行处理完成之后,根据当前行的首节点(我们使用它来维持外部循环),寻找下一行的首节点:如果首节点有左节点,那下一行的首节点就是左节点,没有,则下一行的首节点就是右节点。如果当前行首节点是叶子节点,那么下一行的首节点就是next节点的左节点,右节点……依此类推。
        • 处理当前节点(我们用它来维持外部循环)的右节点时,或者处理当前节点的左节点且当前节点没有右节点时,那么next指针就需要指向当前节点的next节点的左节点,右节点(如果没有左节点)……依此类推。
    • 实现:
      /**
       * Definition for binary tree with next pointer.
       * struct TreeLinkNode {
       *  int val;
       *  TreeLinkNode *left, *right, *next;
       *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
       * };
       */
      class Solution {
      public:
          void connect(TreeLinkNode *root) {
              if (root==NULL){
                  return;
              }
              TreeLinkNode* lineHead = root;
              TreeLinkNode* node = root;
              while(lineHead){
                  node = lineHead;
                  while(node){
                      conectChildren(node);
                      node = node->next;
                  }
                  lineHead = getNext(lineHead);
              }
          }
      private:
          void conectChildren(TreeLinkNode* node){
              // Consider node->left
              if (node->left != NULL){
                  if (node->right!=NULL){
                      node->left->next = node->right;
                  }
                  else{
                      node->left->next = getNext(node->next);
                  }
              }
              // Consider node->right
              if (node->right != NULL){
                  node->right->next = getNext(node->next);
              }
          }
          TreeLinkNode* getNext(TreeLinkNode* node){
              if (node == NULL){
                  return NULL;
              }
              else if (node->left != NULL){
                  return node->left;
              }
              else if (node->right != NULL){
                  return node->right;
              }
              else{
                  return getNext(node->next);
              }
          }
      };
    作者:一叶斋主人
    出处:www.cnblogs.com/yiyezhai
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    14章 InnoDB存储引擎
    archer配置LDAP
    月薪过万的90后,爱情却败给了房子
    postgresql 只改一行就获得100倍性能提升
    数据库优化方面
    greenplum command center gpcc安装文档
    centos6.9 greenplum5.3离线部署文档
    max_prepared_transactions设置不正确时的症状
    MySQL事务隔离级别详解
    激活Windows office jetbrain pycharm goland idea clion
  • 原文地址:https://www.cnblogs.com/yiyezhai/p/2992913.html
Copyright © 2011-2022 走看看