Java 八道经典面试题之链表题
目录
- 第一题 移除链表元素
- 第二题 反转链表
- 第三题 链表的中心结点
- 第四题 倒数第k个结点
- 第五题 合并两个有序链表
- 第六题 链表分割
- 第七题 判断是否回文
- 第八题 相交链表
第一题 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
这道题还是比较简单的我们需要让删除的节点的前一个结点指向删除节点的后一个就行。就比如cur.next==cur.next.next;。
class Solution { public ListNode removeElements(ListNode head, int val) { ListNode header=new ListNode(-1); header.next=head; ListNode cur =header; while(cur.next!=null){ if(cur.next.val==val){ cur.next=cur.next.next; }else{ cur=cur.next; } } return header.next; } }
第二题 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
这也是一个简单题,我们还是先弄一个尾结点,因为链表的最后一个结点的下一个是一个null,这道题我们可以通过一次循环让后一个结点的下一个结点指向前一个结点。
class Solution { public ListNode reverseList(ListNode head) { ListNode pre =null; ListNode cur=head; while(cur!=null){ ListNode next=cur.next; cur.next=pre; pre=cur; cur=next; } return pre; } }
第三题 链表的中心结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
答:这个也是一个简单题我们需要用到快慢指针,当快指针指完之后,慢的结点肯定是中点比如18 快的可以走9步每次走两步走到18,慢的可以每次走一部走9步。刚好到中点。
class Solution { public ListNode middleNode(ListNode head) { ListNode p =head; ListNode q =head; while(q!=null&&q.next!=null){ q=q.next.next; p=p.next; } return p; } }
第四题 倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点
输入:
1,{1,2,3,4,5}
复制
返回值:
{5}
答:这道题也是一个简单题,直接简单粗暴的搞出来倒数第k个点的值就行;
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { ListNode cur=head; ListNode pre=head; int count=0; int x=0; while(cur!=null){ cur=cur.next; count++; } if(k<0||k>count){ return null; } while(pre!=null){ if(x==count-k){ break; }else{ pre=pre.next; x++; } } return pre; } }
这道题写的有点麻烦了,我们也可以用快慢指针做。一个指针走5步一个走4步。
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { ListNode p=head; ListNode q=head; for(int i = 0; i < k; i++) { if (p != null) { p= p.next; } else { return null; } } while(p!=null){ p=p.next; q=q.next; } return q; } }
第五题 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
答:这道题考到了怎么将两个链表合并,我们需要将两个链表从大到小合并起来。
class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode dummyHead = new ListNode(0); ListNode cur = dummyHead; while (l1 != null && l2 != null) { if (l1.val < l2.val) { cur.next = l1; cur = cur.next; l1 = l1.next; } else { cur.next = l2; cur = cur.next; l2 = l2.next; } } // 任一为空,直接连接另一条链表 if (l1 == null) { cur.next = l2; } else { cur.next = l1; } return dummyHead.next; } }
第六题 链表分割
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
输入:l1 = [1,2,1,3,2] 3
输出:[1,2,1,2,3]
这道题比较难了需要我们创建两个链表,一个数大与等于x的链表,另一个数小于x的链表。然后让上一个链表的下一个尾结点指向下一个结点的尾巴结点。
这里我们需要用到如何将两个链表合并成一个链表。
做题的时候先想怎么做然后在动手!
public class Partition { public ListNode partition(ListNode pHead, int x) { if(pHead == null || pHead.next == null) { return pHead; } ListNode newHead = new ListNode(0); ListNode flagHead = new ListNode(0); ListNode newh = newHead; ListNode flagh = flagHead; while(pHead != null){ if(pHead.val < x){ newh.next = new ListNode(pHead.val); newh = newh.next; }else{ flagh.next = new ListNode(pHead.val); flagh = flagh.next; } pHead = pHead.next; } newh.next = flagHead.next; return newHead.next; } }
第七题 判断是否回文
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
1->2->2->1
返回:true
public class PalindromeList { public boolean chkPalindrome(ListNode head) { // write code here ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null) { fast = fast.next.next; slow = slow.next; } ListNode cur=slow.next; while(cur!=null){ ListNode curNext=cur.next; cur.next=slow; slow=cur; cur=curNext; } //3.一个从前往后,一个从后往前 如果相遇,则证明回文 while(head!=slow){ if(head.val!=slow.val){//先判断值是否相等 return false; } if(head.next==slow){//偶数情况下 return true; } head=head.next; slow=slow.next; } return true; }
第八题 相交链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
可以用笨方法就是计算出来每个链表的个数然后让多的先走。
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) { return null; } ListNode last = headB; while (last.next != null) { last = last.next; } last.next = headB; ListNode fast = headA; ListNode slow = headA; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { slow = headA; while (slow != fast) { slow = slow.next; fast = fast.next; } last.next = null; return fast; } } last.next = null; return null; } }
到此这篇关于Java 八道经典面试题之链表题的文章就介绍到这了,更多相关Java 链表题内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!