原文作者:aircraft
原文链接:https://www.cnblogs.com/DOMLX/p/11209807.html
一.1道网易c++的面试题
我当时第一时间的解答方案
#include#include 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 > Windows(0, vector (4)); vector Window; vector > pos(0, vector (2)); vector po; vector nums; vector 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<
二.环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 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_mapint > 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................