八道经典的面试链表题--------快乐人的java巩固日记[1]

Posted 编程快乐人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八道经典的面试链表题--------快乐人的java巩固日记[1]相关的知识,希望对你有一定的参考价值。


初次做oj题可能大家会不习惯,所以我们要慢慢来。

第一题 移除链表元素

给你一个链表的头节点 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巩固日记[1]的主要内容,如果未能解决你的问题,请参考以下文章

面试官常考的15道链表题,你会多少?建议收藏

链表题 面试题02.04. 分割链表290. 单词规律20. 有效的括号

《手撕链表题系列-7》链表的回文结构

看一遍就理解,图解单链表反转

看一遍就理解,图解单链表反转

剑指offer 面试25题