c++ LeetCode (网易面试题和链表以及树篇) 五道算法例题代码详解(三)

  • 2019 年 10 月 6 日
  • 筆記

一.1道网易c++的面试题

 我当时第一时间的解答方案

#include <iostream>  #include <vector>    using namespace std;    int main()  {  	const int Wi = 3840;  	const int Hi = 2160;  	int N,M;  	int temp;  	int x,y,w,h;  	int x1,y1;  	int b;  	vector<vector<int> > Windows(0, vector<int> (4));  	vector<int> Window;  	vector<vector<int> > pos(0, vector<int> (2));  	vector<int> po;  	vector<int> nums;      vector<int> SX;  	cin >> N >> M;  	if(N<=0 || M >= 1000) return 0;  	for(int i = 0;i < N;i++){          SX.emplace_back(N-i);  		cin>>x>>y>>w>>h;  		Window.emplace_back(x);  		Window.emplace_back(y);  		Window.emplace_back(w);  		Window.emplace_back(h);  		Windows.emplace_back(Window);  		Window.clear();  	}    	for(int j = 0; j < M; j++){  		cin>>x1>>y1;  		po.emplace_back(x1);  		po.emplace_back(y1);  		pos.emplace_back(po);  		po.clear();  	}  	for(int k = 0; k < M; k++){  		int flag = -1;  		for(int i = 0; i < N; i++){  			if(flag = -1)  			if(Windows[SX[i] - 1][0] <= pos[k][0] && (Windows[SX[i] -1][0]+Windows[SX[i] -1][2])>=pos[k][0] && Windows[SX[i]-1][1] <= pos[k][1] && (Windows[SX[i]-1][1]+Windows[SX[i]-1][3])>=pos[k][1]){  				flag = SX[i];  				int size = SX.size();  				for(int j = i - 1; j >= 0 ;j--){  					SX[j + 1] = SX[j];  				}  				SX[0] = flag;  				break;  			}    		}  		nums.emplace_back(flag);  		flag = -1;  	}  	for(auto num:nums){  		cout<<num<<endl;  	}  }

二.环形链表

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,-4], pos = 1  输出:true  解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0  输出:true  解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1  输出:false  解释:链表中没有环。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

我的代码:20ms

/**   * Definition for singly-linked list.   * struct ListNode {   *     int val;   *     ListNode *next;   *     ListNode(int x) : val(x), next(NULL) {}   * };   */  class Solution {  public:      bool hasCycle(ListNode *head) {          if(head == NULL) return false;          unordered_map<ListNode*,int> umap;          ListNode *node = head;          while(node->next != NULL){              umap[node]++;              if(umap[node] > 1) return true;              node = node->next;            }          return false;      }  };

我的思路就是把每个链表遍历存储在map容器中,出现已经存放的地址时申请再次存放时,这时候就是环形链表。

大佬们的代码5ms左右:

class Solution {  public:      bool hasCycle(ListNode *head) {          if(head == NULL)              return false;          ListNode *slow,*fast;          slow = head;          fast = head;          while(slow && fast)          {              slow = slow->next;              fast = fast->next;              if(fast)                  fast = fast->next;              else                  return false;              if(slow == fast)                  return true;          }          return false;      }  };

这个代码思路就是快慢指针,如果链表出现环形,那么我的快慢指针一定会相遇。

3.二叉树的最大深度:

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例: 给定二叉树 [3,9,20,null,null,15,7]

    3     /     9  20      /       15   7

返回它的最大深度 3

我的代码:16ms

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      int count = 0;      int max = 0;      int maxDepth(TreeNode* root) {          if(root == NULL) return 0;          count++;          if(count > max) max = count;          maxDepth(root->left);          maxDepth(root->right);          count--;          return max;      }  };

 我的思路就是全部遍历一遍,记录最大深度。

大佬的代码:4ms

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:        int detectDepth(TreeNode* node) {          if (!node) return 0;          int leftDepth = 1 + detectDepth(node -> left);          int rightDepth = 1 +  detectDepth(node -> right);          return std::max(leftDepth, rightDepth);      }        int maxDepth(TreeNode* root) {          return detectDepth(root);      }  };

这个代码就是跟我的思路差不多,不过用递归的方法优化,比我好多了。

4.验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:      2     /     1   3  输出: true

示例 2:

输入:      5     /     1   4       /       3   6  输出: false  解释: 输入为: [5,1,4,null,null,3,6]。       根节点的值为 5 ,但是其右子节点值为 4 。    我的代码24ms
/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      bool flag = 1;      int ergodic(TreeNode* root,long min,long max){          if(root == NULL) return 0;          if(root->left != NULL){              if(root->left->val >= root->val || root->left->val <= min){                  flag = 0;                  return 0;              }              ergodic(root->left,min,root->val);          }          if(root->right != NULL){              if(root->right->val <= root->val || root->right->val >= max){                  flag = 0;                  return 0;              }              ergodic(root->right,root->val,max);          }          return 0;      }      bool isValidBST(TreeNode* root) {          if(root == NULL) return 1;          if(root->left != NULL){              if(root->left->val >= root->val){                  flag = 0;                  return 0;              }              ergodic(root->left,LONG_MIN,root->val);          }          if(root->right != NULL){              if(root->right->val <= root->val){                  flag = 0;                  return 0;              }              ergodic(root->right,root->val,LONG_MAX);          }            return flag;      }  };

 我的方法就是递归遍历加上数值判断

大佬的代码:8ms

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      bool isValidBST(TreeNode* root, long long min = LONG_LONG_MIN, long long max = LONG_LONG_MAX) {          if(root == NULL)  return true;          if(root->val <= min || root->val >= max)      return false;            return isValidBST(root->left, min, root->val) && isValidBST(root->right, root->val, max);      }  };

这个代码其实思路是跟我差不多的,但是代码的简洁和调用库函数来判断,比我那乱七八糟的好太多了。

5.对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    1     /     2   2   /  /   3  4 4  3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1     /     2   2             3    3

说明:

如果你可以运用递归和迭代两种方法解决这个问题,会很加分。

我的代码:8ms

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      int flag = 1;      int left = 0;      int right = 0;      vector<int> leftTree,rightTree;      void leftRecursiveComparison(TreeNode* root){          if(root){              left++;              leftRecursiveComparison(root->left);              leftTree.emplace_back(root->val);              leftRecursiveComparison(root->right);          }          else leftTree.emplace_back(left);      }      void rightRecursiveComparison(TreeNode* root){          if(root){              right++;              rightRecursiveComparison(root->right);              rightTree.emplace_back(root->val);              rightRecursiveComparison(root->left);          }          else rightTree.emplace_back(right);      }      bool isSymmetric(TreeNode* root) {          if(root == NULL) return true;          leftRecursiveComparison(root->left);          rightRecursiveComparison(root->right);          int lenLeft = leftTree.size();          int lenRight = rightTree.size();          if(lenLeft != lenRight) return false;          for(int i = 0; i < lenLeft; i++){              cout<<rightTree[i];              if(leftTree[i] != rightTree[i])                  return false;          }            return true;      }  };

 我的思路已经不想讲了 ,直接看大佬的吧。

大佬们的代码:1ms左右

class Solution {  public:      bool isSymmetric(TreeNode* root) {          if(root==nullptr) return true;          return helper(root->left,root->right);      }      bool helper(TreeNode* left,TreeNode* right){          if(left==nullptr&&right==nullptr) return true;          if(left==nullptr||right==nullptr) return false;          return (left->val==right->val)&&helper(left->left,right->right)              &&helper(left->right,right->left);      }  };

大佬这个就是同时对两边的子树进行递归遍历,然后需要对称的值进行判断。

哎,看看自己跟大佬们的代码就知道差距了QAQ…………….