题目描述
解题思路
设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。
当访问链表 A 的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问链表 B 的指针
访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访
问到交点。
public ListNode findFirstCommonNode(ListNode node1,ListNode node2) {
ListNode l1=node1;
ListNode l2=node2;
while(l1!=l2) {
l1=(l1==null)?node2:l1.next;
l2=(l2==null)?node1:l2.next;
}
return l1;
}
我们还可以借助栈来完成。先把两个链表依次装到两个栈中,然后比较两个栈的栈顶结点是否相同,如果相同则出栈,如果不同,那最后相同的结点就是我们要的返回值。
// 利用栈的方法
public ListNode findFirstCommonNodeByStack(ListNode node1, ListNode node2) {
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
if (node1 != null) {
stack1.push(node1);
node1 = node1.next;
}
if (node2 != null) {
stack2.push(node2);
node2 = node2.next;
}
ListNode node=null;
if(!stack1.isEmpty()&&!stack2.isEmpty()&&stack1.peek()==stack2.peek()) {
stack1.pop();
node=stack2.pop();
}
return node;
}
题目描述
统计一个数字在排序数组中出现的次数。
Input: nums = 1, 2, 3, 3, 3, 3, 4, 6
K = 3 Output: 4
解题思路
通过二分查找,找到k的第一个开始下标和最后一个的下标
//利用二分查找的方法
public int getNumberTime(int[] nums, int k) {
int len = nums.length;
if (len == 0) {
return 0;
}
int first = getFirst(nums, k, 0, len - 1);
int last = getLast(nums, k, 0, len - 1);
if (first != -1 && last != -1) {
return last - first + 1;
}
return 0;
}
private int getLast(int[] nums, int k, int start, int end) {
int mid;
while (start <= end) {
mid = start + (end - start) / 2;
if (k >= nums[mid]) {
start = mid + 1;
} else {
end = mid - 1;
}
}
if (end >= 0 && nums[end] == k) {
return end;
}
else {
return -1;
}
}
private int getFirst(int[] nums, int k, int start, int end) {
int mid;
while (start <= end) {
mid = start + (end - start) / 2;
if (k <= nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
}
if (start < nums.length && nums[start] == k) {
return start;
} else {
return -1;
}
}
优化版本的二分查找
//优化版本的通过二分查找
public int getNumberTime1(int[] nums,int k){
int first=binarySearch(nums, k);
int last=binarySearch(nums,k+1);
return (first==nums.length||nums[first]!=k)?0:last-first;
}
private int binarySearch(int[] nums, int k) {
int start=0;
int end=nums.length;
while(start<end) {
int m=start+(end-start)/2;
if(nums[m]>=k) {
end=m;
}else {
start=m+1;
}
}
return start;
}
我们还可以通过k+0.5,k-0.5,直接搜索k-0.5和k+0.5这两个数应该插入的位置,然后相减即可。
//直接搜索k-0.5和k+0.5这两个数应该插入的位置,然后相减即可。
public int getNumberTime2(int[] nums, int k) {
return binarySearch(nums, k + 0.5) - binarySearch(nums, k - 0.5);
}
private int binarySearch(int[] nums, double k) {
int start = 0;
int end = nums.length ;
while(start<=end) {
int m=start+(end-start)/2;
if(nums[m]>k) {
end=m-1;
}else {
start=m+1;
}
}
return start;
}