c++ LeetCode (網易面試題和鏈表以及樹篇) 五道算法例題代碼詳解(三)

 

 

原文做者:aircrafthtml

原文連接:https://www.cnblogs.com/DOMLX/p/11209807.html前端

 

一.1道網易c++的面試題node

 

 

 

 

 我當時第一時間的解答方案python

#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;
	}
}

 

 

二.環形鏈表ios

給定一個鏈表,判斷鏈表中是否有環。c++

爲了表示給定鏈表中的環,咱們使用整數 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,機器學習深度學習之類有關於基礎編程,圖像處理和機器視覺開發的知識

 

相關文章
相關標籤/搜索