1. 两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
分析:借鉴牛客官方解法的思路,将每个链表接在对方链表的前面,利用双指针在两个链表上同步移动。如果两链表本身长度不相等,两指针就需要跨越空指针 nullptr 才能同时指向公共结点。需要注意的是,如果两链表本身相等,两指针就一定不会遍历到空指针处。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* l1= pHead1, *l2=pHead2;
while(l1!=l2)
{
l1 = l1?l1->next:pHead2;
l2 = l2?l2->next:pHead1;
}
return l1;
}
};
2. 数字在排序数组中出现的次数
统计一个数字在排序数组中出现的次数。
分析:请注意是数组本身是升序的,用二分法能更快找到数组中等于某数字的范围,这个范围用上下界标识。上界一定指向比目标值大的数,而下界指向第一个目标值,如果目标值不存在,指向比目标值大的数。这样上下界相减就是该数字出现的次数。问题在于怎么找上下界。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int num = data.size(), l=0, r=num, mid, upbound, downbound;
if(num==0) return 0;
//找上界;
while(l<r){
mid = l+(r-l)/2;
//为什么是>,而不是>=; 为什么是mid,而不是mid-1
if(data[mid]>k) r = mid;
//为什么是mid+1,而不是mid
else l = mid+1;
}
upbound = r;
//找下界。
l=0; r=num;
while(l<r){
mid = l+(r-l)/2;
//为什么是>=,而不是>; 为什么是mid,而不是mid-1
if(data[mid]>=k) r = mid;
//为什么是mid+1,而不是mid
else l = mid+1;
}
downbound = r;
return upbound-downbound;
}
};