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

    原文作者:aircraft

    原文链接:https://www.cnblogs.com/DOMLX/p/11209807.html

    一套面试题的目录在此,还在继续完善中。。。。。。

    c/c++ 2019面试题目录

    一.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................

    若有兴趣交流分享技术,可关注本人公众号,里面会不定期的分享各种编程教程,和共享源码,诸如研究分享关于c/c++,python,前端,后端,opencv,halcon,opengl,机器学习深度学习之类有关于基础编程,图像处理和机器视觉开发的知识

  • 相关阅读:
    [bochs]反编译的代码只能参考参考
    [Linux命令]dd
    exp1orer.exe木马解除方法
    江民公布“密码7005”最新变种技术报告
    广外女生1次惊心动魄的卸载
    [病毒]exp1orer.exe
    [Win2003]禁用关机原因调查
    获得本机IP地址
    一段连接FTP的VC代码
    [Perl]FTP自动上传文件的脚本以及配置文件
  • 原文地址:https://www.cnblogs.com/DOMLX/p/11209807.html
Copyright © 2011-2022 走看看