链表常见题型

来源:互联网 发布:json怎么用 编辑:程序博客网 时间:2024/04/28 06:31

环形链表插值练习题

有一个整数val,如何在节点值有序的环形链表中插入一个节点值为val的节点,并且保证这个环形单链表依然有序。
给定链表的信息,及元素的值A及对应的nxt指向的元素编号同时给定val,请构造出这个环形链表,并插入该值。
测试样例:
[1,3,4,5,7],[1,2,3,4,0],2
返回:{1,2,3,4,5,7}

分析:
一共有三种情况
1、如果原链表为空
2、如果链表不为空
3、如果p和c转一圈都没有发现应该插入的位置,此时node应该插入头节点的前面

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class InsertValue {    public ListNode insert(int[] A, int[] nxt, int val) {        if (A == null || A.length == 0){            ListNode node = new ListNode(val);            return node;        }        ListNode head = new ListNode(A[0]);        // 构建有序链表(并非环形,因为不能题目不让返回环形)        ListNode headTemp = head;        for (int i = 0; i < A.length-1; i++){            ListNode temp = new ListNode(A[nxt[i]]);            headTemp.next = temp;            headTemp = temp;        }        // 如果值小于链表头部值,则插入头部,且返回node链表        if (val < head.val){            ListNode node = new ListNode(val);            node.next = head;            return node;        }        // 循环遍历,寻找合适的位置插入        ListNode pre = head;        ListNode cur = pre.next;        while (cur != null){            if (val >= pre.val && val <= cur.val){                break;            }            pre = cur;            cur = cur.next;        }        // 要么是找到了合适的位置(break出来),要么是val都大于链表值,在最后位置插入        ListNode node = new ListNode(val);        node.next = cur;        pre.next = node;        return head;    }}

访问单个节点的删除练习题

实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。
给定带删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true

分析:
1、下一个节点指向删除的节点,然后删除下一个节点

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class Remove {    public boolean removeNode(ListNode pNode) {        // 空节节不能删除        if (pNode == null){            return false;        }        ListNode next = pNode.next;        // 空节点不能赋值给节点        if (next == null){            return false;        }        pNode.val = next.val;        pNode.next = next.next;        return true;    }}

链表的分化练习题

对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。
给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。
测试样例:
{1,4,2,5},3
返回结果:
{1,2,4,5}
分析:
1、建立两个链表:小于等于val链表,大于val链表

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class Divide {    public ListNode listDivide(ListNode head, int val) {        if (head == null || head.next == null){            return head;        }        // 当前节点        ListNode curNode = head, temp = null;        // 小于val的链表与尾节点        ListNode smallerHead = null, smallerTail = null;        // 与大于val的链表与尾节点        ListNode biggerHead = null, biggerTail = null;        while (curNode != null){            // 取出第一个节点            temp = curNode;            curNode = curNode.next;            // 避免其它链表连接后成为闭环            temp.next = null;            int value = temp.val;            if (value <= val){                // 如果是第一个,则附头                if (smallerHead == null){                    smallerHead = temp;                }                // 如果不是第一个,则尾部添加                else{                    smallerTail.next = temp;                }                // 尾部指向最后一个                smallerTail = temp;            }            else {                 // 如果是第一个,则附头                if (biggerHead == null){                    biggerHead = temp;                }                // 如果不是第一个,则尾部添加                else{                    biggerTail.next = temp;                }                // 尾部指向最后一个                biggerTail = temp;            }        }        // 如果小的链表没值,则返回大的链表        if (smallerHead == null){            return biggerHead;        }        // 如果大的链表没值,则返回小的链表        if (biggerHead == null){            return smallerHead;        }        // 小链表与大链表连接        smallerTail.next = biggerHead;        return smallerHead;    }}

打印两个链表的公共值练习题

现有两个升序链表,且链表中均无重复元素。请设计一个高效的算法,打印两个链表的公共值部分。
给定两个链表的头指针headA和headB,请返回一个vector,元素为两个链表的公共部分。请保证返回数组的升序。两个链表的元素个数均小于等于500。保证一定有公共值
测试样例: {1,2,3,4,5,6,7},{2,4,6,8,10}
返回:[2.4.6]

分析:
1、两数比较,小的自己+1,等于的装进数组,然后都+1

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class Common {    public int[] findCommonParts(ListNode headA, ListNode headB) {        List<Integer> list = new ArrayList<>();        while (headA != null && headB != null){            if (headA.val < headB.val){                headA = headA.next;            }            else if (headA.val > headB.val){                headB = headB.next;            }            else{                list.add(headA.val);                headA = headA.next;                headB = headB.next;            }        }        int[] a = new int[list.size()];        for (int i = 0; i < list.size(); i++)        {            a[i] = list.get(i);        }        return a;    }}

链表的k逆序练习题

有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。例如链表1->2->3->4->5->6->7->8->null,K=3这个例子。调整后为,3->2->1->6->5->4->7->8->null。因为K==3,所以每三个节点之间逆序,但其中的7,8不调整,因为只有两个节点不够一组。 给定一个单链表的头指针head,同时给定K值,返回逆序后的链表的头指针。

分析:
1、使用栈存储3个数,出栈就是倒序啦。里边有许多的细节需要画图处理的

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class KInverse {    public ListNode inverse(ListNode head, int k) {        if (k < 2){            return head;        }        Stack<ListNode> stack = new Stack<>();        ListNode newHead = head, cur = head;        // 上一个链表的末端,下一个链表的开始        ListNode preEnd = null, nextStart = null;        while (cur != null){            nextStart = cur.next;            stack.push(cur);            if (stack.size() == k){                preEnd = reload(stack, preEnd, nextStart);                // 因为逆序了,所以头结点需要改变(就一次)                if (newHead == head){                    newHead = cur;                }            }            cur = nextStart;        }        return newHead;    }    public ListNode reload(Stack<ListNode> stack, ListNode preEnd, ListNode nextStart){        ListNode cur = stack.pop();        // 如果不等于null,则上一个末端(preEnd)直接连接当前(cur)的节点        if (preEnd != null){            preEnd.next = cur;        }        ListNode next = null;        while (!stack.isEmpty()){            next = stack.pop();            cur.next = next;            cur = next;        }        // 三个节点中的最后一个节点与下一个链表(nextStart)连接        cur.next = nextStart;        // 返回当前链表的最后一个节点        return cur;    }}

链表指定值清除练习题

现在有一个单链表。链表中每个节点保存一个整数,再给定一个值val,把所有等于val的节点删掉。
给定一个单链表的头结点head,同时给定一个值val,请返回清除后的链表的头结点,保证链表中有不等于该值的其它值。请保证其他元素的相对顺序。
测试样例:
{1,2,3,4,3,2,1},2
返回值:
{1,3,4,3,1}

分析:
1、遍历链表,一样的值则删除掉

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class ClearValue {    public ListNode clear(ListNode head, int val) {        // 避免头部为一样值        while (head != null){            if (head.val != val)                break;            head = head.next;        }        ListNode pre = head;        ListNode cur = head;        // 遍历链表,一样的值则删除        while (cur != null){            if (cur.val == val){                pre.next = cur.next;            }            else {                pre = cur;            }            cur = cur.next;        }        return head;    }}

链表的回文结构练习题

请编写一个函数,检查链表是否为回文。 给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}

分析:
回文:是否对称
1、将数据全入栈,出栈的时候与链表一一比较,都相等则回文。。

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class Palindrome {    public boolean isPalindrome(ListNode pHead) {        if (pHead == null){            return false;        }        Stack<ListNode> stack = new Stack<>();        // 将节点都放到栈里        ListNode cur = pHead;        while (cur != null){            stack.push(cur);            cur = cur.next;        }        // 出栈,看是否全都相等        ListNode temp = null;        cur = pHead;        while (!stack.isEmpty()){            temp = stack.pop();            if (temp.val != cur.val){                return false;            }            else {                cur = cur.next;            }        }        return true;    }}

链表判环练习题

如何判断一个单链表是否有环?有环的话返回进入环的第一个节点的值,无环的话返回-1。如果链表的长度为N,请做到时间复杂度O(N),额外空间复杂度O(1)。
给定一个单链表的头结点head(注意另一个参数adjust为加密后的数据调整参数,方便数据设置,与本题求解无关),请返回所求值。

import java.util.*;class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}public class ChkLoop {    public int chkLoop(ListNode head, int adjust) {        ListNode fast = head;        ListNode slow = head;        boolean circle = false;        while (fast != null && fast.next != null){            fast = fast.next.next;            slow = slow.next;            // 当相等时说明是闭环;            if (fast == slow){                circle = true;                break;            }        }        if (circle == false){            return -1;        }        // fast再从头来开始,当它们再次相遇说明是入口点;        fast = head;        while(fast != slow){            fast = fast.next;            slow = slow.next;        }        return fast.val;    }}

0 0
原创粉丝点击