面试题1
给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
思路:定义快慢指针,一个慢指针正常往后走,一个快指针按照慢指针的2倍速度进行遍历。最好是快指针走的是2步。
public ListNode func1(){
ListNode fast = head;
ListNode slow = head;
while (fast != null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
面试题2
思路:定义快慢指针,快指针先走k-1步,当快指针走到尾节点的时候,就返回慢指针
![](https://i-blog.csdnimg.cn/blog_migrate/d0441bee050e5fb35a3dcfd97419c4ec.png)
public ListNode func2(int k){
// 1.判断合法性
if (k<= 0 || head==null){
return null;
}
// 2.合法的情况进行查找
ListNode fast = head;
ListNode slow = head;
for (int i = 1; i < k; i++) {
//fast先走k-1步
fast = fast.next;
if(fast == null){
// 判断如果走完k-1步fast为null,则说明给的k大于size了
return null;
}
}
// 正常往后走
while (fast.next != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
面试题3
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路:创建一个新的节点,里面存储为第一个比较大小的地址,作为最终的头结点,创建指针temp进行走动,分别比较两个链表里面的val值,如果head1.val值大于head2.val,那么就将tmp的next指向head2;head2往下走,tmp往head2这个方向走,再与head1进行比较,如果head1小,就将tmp的next指向head1,head1往后走,tmp往head1这个方向走。
![](https://i-blog.csdnimg.cn/blog_migrate/a9c4bbf927675789d71698274828c30e.png)
public static work.ListNode func2(work.ListNode head1, work.ListNode head2){
// 定义一个临时节点
work.ListNode newHead = new work.ListNode(0);
work.ListNode tmp = newHead;
while (head1 != null && head2 !=null){
if (head1.val < head2.val){
tmp.next = head1;
head1 = head1.next;
tmp = tmp.next;
}else {
tmp.next = head2;
head2 = head2.next;
tmp = tmp.next;
}
}
if (head1 != null){
tmp.next = head1;
}
if (head2 != null){
tmp.next = head2;
}
return newHead.next;
}
![](https://i-blog.csdnimg.cn/blog_migrate/fbf4cfac5407561179f2fc67988a222a.png)
面试题4
链表的回文结构。
![](https://i-blog.csdnimg.cn/blog_migrate/ac94c8d4382e7b4f9cb0f192da48bd54.png)
判断是否为空链表
判断是否只有一个节点
思路:寻找中间节点,反转中间节点后面的部分,然后进行遍历,判断是否相等,奇数情况下最后一对相等的是不相邻的,但是偶数节点最后一对相等的值一定是想等的
实现:
1.寻找中间节点(快慢指针,快指针速度是慢指针2倍)
2.翻转中间节点以后得部分
![](https://i-blog.csdnimg.cn/blog_migrate/6b12bf8057d8d8b9b50cbc2dedfb5a89.png)
3.进行比较(奇数情况:直到head和slow进行相遇 偶数情况:head.next == slow(head与slow相邻))
![](https://i-blog.csdnimg.cn/blog_migrate/9f971d6762e311c49da10eeb264dd534.png)
public boolean chkPalindrome(){
//判断是否为空链表
if (head == null){
return false;
}
if (head.next == null){
return true;
}
ListNode fast = head;
ListNode slow = head;
while (fast != null&&fast.next!=null){
// 1.找中间节点
fast = fast.next.next;
slow = slow.next;
}
//2.翻转 (中间节点之后的部分)
ListNode cur = slow.next; // 代表当前需要翻转的节点
while (cur!=null){
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//3.一个从前往后,一个从后往前
while (slow != head){
if(head.val != slow.val){
return false;
}
if (head.next == slow){
// 偶数情况下, 判断最后是否相邻,相邻就返回true
return true;
}
head = head.next;
slow = slow.next;
}
return true;
}