二叉树的最大深度
题目链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
法一 递归
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
else
{
int left_height=maxDepth(root->left)+1;
int right_height=maxDepth(root->right)+1;
return left_height>right_height?left_height:right_height;
}
}
};
很简单的思路。。虽然通过了,但还是有栈溢出或超时的风险
法二 循环
class Solution {
public:
int maxDepth(TreeNode* root) {
stack< pair<TreeNode*,int> > st;
if(root==NULL)
return 0;
st.push(make_pair(root,1));
int depth=0;
while(!st.empty())
{
TreeNode* cur=st.top().first;
int cur_val=st.top().second;
st.pop();
if(cur_val>depth)
depth=cur_val;
if(cur->left)
st.push(make_pair(cur->left,cur_val+1));
if(cur->right)
st.push(make_pair(cur->right,cur_val+1));
}
return depth;
}
};
深度优先遍历(因为是栈),举个例子会很明白。
只出现一次的数字
题目链接:https://leetcode-cn.com/problems/single-number/
直接异或即可,因为2个相同的数异或结果是0,而任何数和0异或都是其本身。并且异或运算满足交换律。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=nums[0];
for(int i=1;i<nums.size();i++)
{
res^=nums[i];
}
return res;
}
};
最小栈
题目链接 https://leetcode-cn.com/problems/min-stack/
法一 记录最小下标即可
class MinStack {
public:
/** initialize your data structure here. */
vector<int> vt;
int min_index=0;
MinStack() {
}
void push(int x) {
vt.push_back(x);
if(x<vt[min_index])
min_index=vt.size()-1;
}
void pop() {
if(!vt.empty())
{
vt.pop_back();
//如果弹出的是最小元素
if(min_index==vt.size())
{
min_index=0;
for(int i=1;i<vt.size();i++)
{
if(vt[i]<vt[min_index])
min_index=i;
}
}
}
}
int top() {
int size=vt.size();
return vt[size-1];
}
int getMin() {
return vt[min_index];
}
};
法二 增加一个辅助栈专门记录最小数值
class MinStack {
public:
stack<int> s;//数据栈
stack<int> min;//辅助栈
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
s.push(x);
if(min.empty()||x<=min.top())
{
min.push(x);
}
}
void pop() {
if(s.top()==min.top())
min.pop();
s.pop();
}
int top() {
return s.top();
}
int getMin() {
return min.top();
}
};
相交链表
题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/
法一 思路比较简单:获取2个链表的长度,然后长的链表先走掉长度之差,然后再同时往前走,直到重合或都到头(表示2个链表不相交)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB)
return NULL;
int lenA=0;
int lenB=0;
ListNode *A=headA;
ListNode *B=headB;
while(A)
{
lenA++;
A=A->next;
}
while(B)
{
lenB++;
B=B->next;
}
A=headA;
B=headB;
if(lenA>lenB)
{
int len=lenA-lenB;
while(len--)
{
A=A->next;
}
}
else
{
int len=lenB-lenA;
while(len--)
{
B=B->next;
}
}
while(A!=B&&A&&B)
{
A=A->next;
B=B->next;
}
return A;
}
};
法二 双指针法
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB)
return NULL;
ListNode *p=headA;
ListNode *q=headB;
int i=1;
int j=1;
while(p&&q&&p!=q)
{
p=p->next;
if(!p&&i)
{
p=headB;
i-=1;
}
q=q->next;
if(!q&&j)
{
q=headA;
j-=1;
}
}
if(p==q&&p)
return p;
else
return NULL;
}
};
一定要有i,j否则会陷入死循环
推荐解答的另一种方法没看懂。。
求众数
题目链接 https://leetcode-cn.com/problems/majority-element/
法一 排序法
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
}
};
法二 投票计数法
class Solution {
public:
int majorityElement(vector<int>& nums) {
int cnt=1;
int num=nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i]==num)
cnt++;
else if(cnt>1)
cnt--;
else if(cnt==1)
{
i++;
num=nums[i];
}
}
return num;
}
};
法三 分治法
法四 哈希
反转链表
题目链接:https://leetcode-cn.com/problems/reverse-linked-list/
法一 循环
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL)
return NULL;
ListNode *pre=NULL;
ListNode *now=head;
while(now)
{
ListNode *temp=now->next;
now->next=pre;
pre=now;
now=temp;
}
return pre;
}
};
法二 迭代(不太好理解)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head||!head->next)
return head;
ListNode *p=reverseList(head->next);
head->next->next=head;
head->next=NULL;
return p;
}
};