链表常见题型
来源:互联网 发布: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; }}
- 链表常见题型
- 面试中常见链表题型整理
- 链表常见题型(java版)
- 有关链表的常见题型
- 常见题型解法
- 面试常见题型总结
- 动态规划常见题型
- javaweb常见面试题型
- CTF常见的题型
- CTF常见题型
- 数据结构(一)顺序表3:顺序表常见题型
- 数据库中几种常见的题型
- 单链表的常见题型汇总
- 常见易错点的程序题型
- 动态规划算法常见题型
- 约瑟夫环问题------链表题型
- 有趣的链表相关题型
- C#常见题型及部分答案
- 学习c语言的第一天i
- LightOJ1341 Aladdin and the Flying Carpet
- win10 uwp 截图 获取屏幕显示界面保存图片
- php中$this->是什么意思??
- UVA 1398 Meteor(扫描线)
- 链表常见题型
- Java NIO概述
- printf计算参数是从右到左压栈的原理(a++和++a的压栈的区别)
- 浅谈进程与线程的关系
- JSONP跨域的原理解析
- iOS/Android车牌扫描识别技术
- USACO动态规划二测总结
- springmvc拦截器
- .gitignore文件中/的认识