36 两个链表的第一个公共节点 题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
思路:
先求出两个链表的长度,让较长的链表先走两链表长度差的距离,然后两个链表同时走,直到遇到公共节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : ListNode* FindFirstCommonNode ( ListNode* pHead1, ListNode* pHead2) { if (!pHead1||!pHead2)return nullptr ; int len1=0 ,len2=0 ; ListNode* h1=pHead1,*h2=pHead2; while (h1->next||h2->next){ if (h1->next){ h1=h1->next; len1++; } if (h2->next){ h2=h2->next; len2++; } } h1=len1>len2?pHead1:pHead2; h2=len1<=len2?pHead1:pHead2; int i=abs (len1-len2); while (i>0 ){ h1=h1->next; i--; } while (h1!=h2){ h1=h1->next; h2=h2->next; } return h1; } };
37 数字在升序数组中出现的次数 题目描述
统计一个数字在升序数组中出现的次数。
思路:
找到一个数在数组中的位置,一般用二分查找。
由于data中都是整数,我们可以搜索k-0.5和k+0.5,这两个数的插入位置做差刚好就是k出现的次数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution {public : int GetNumberOfK (vector<int > data ,int k) { return search (data,0 ,data.size ()-1 ,k+0.5 )-search (data,0 ,data.size ()-1 ,k-0.5 ); } int search (vector<int > &data,int l,int r,double k) { int mid; while (l<=r){ mid=l+(r-l)/2 ; if (data[mid]<k){ l=mid+1 ; } else if (data[mid]>k){ r=mid-1 ; } } return l; } };
38 二叉树的深度 题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
示例1
输入:
返回值:
思路:
深度搜索二叉树,每一层都记录层数,返回层数最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : int TreeDepth (TreeNode* pRoot) { if (!pRoot)return 0 ; int dep=0 ; dfs (1 ,dep,pRoot); return dep; } void dfs (int cur,int &dep,TreeNode* pRoot) { if (pRoot->left)dfs (cur+1 ,dep,pRoot->left); if (pRoot->right)dfs (cur+1 ,dep,pRoot->right); dep=max (dep,cur); } };
39 平衡二叉树 题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树 (Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
示例1
输入:
返回值:
思路:
深度搜索二叉树,记录每个子树的高度,设置一个标志b,若左右子树的高度差大于一,b=false停止遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : bool IsBalanced_Solution (TreeNode* pRoot) { if (!pRoot)return true ; bool res=true ; dfs (res,pRoot); return res; } int dfs (bool &b,TreeNode* root) { if (!b)return -1 ; if (!root)return 0 ; int left=dfs (b,root->left); if (!b)return -1 ; int right=dfs (b,root->right); if (abs (left-right)>1 )b=false ; return max (left,right)+1 ; } };
40 数组中只出现一次的数字 题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
示例1
输入:
返回值:
说明:
思路:
利用unordered_map统计每一个数出现的次数,最后返回只出现一次的数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <unordered_map> class Solution {public : vector<int > FindNumsAppearOnce (vector<int >& array) { unordered_map<int ,int > map; vector<int > res; for (auto i:array){ map[i]++; } for (auto m:map){ if (m.second==1 ){ res.push_back (m.first); } } if (res[0 ]>res[1 ])swap (res[0 ],res[1 ]); return res; } };
41 和为S的连续正数序列 题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
返回值描述:
1 输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
示例1
输入:
返回值:
思路:
利用双指针或者说滑动窗口,根据窗口内数的和确定窗口的位置和宽度。
若和等于sum,将窗口内的数添加到结果中,若小于sum右指针右移,若大于sum,左指针右移
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution {public : vector<vector<int > > FindContinuousSequence (int sum) { int l=1 ,r=2 ; vector<vector<int >> res; while (r>l){ int num=(l+r)*(r-l+1 )/2 ; if (num==sum){ vector<int > p; for (int i=l;i<=r;i++){ p.push_back (i); } res.push_back (p); } if (num<sum)r++; else l++; } return res; } };