✅?个人主页:程序猿追
✅?系列专栏:算法合集
✅?目前状态:创建Java学习之路(零基础到就业实战)系列,目前更新到JAVAWEB开发
✅?作者简介:大家好,我是程序猿追,全栈领域新星创作者,算法爱好者,常在作者周榜排名前30,某不知名的 ACMer
✅?推荐一款刷题面试找工作三不误的网站——牛客网
✅?个人名言:不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!
目录
?前言
?反转链表
?题解代码
?链表区间反转
?题解代码
?链表的奇偶重排
?题解代码
?链表中的节点每k个一组翻转
?题解代码
前言
哈喽,大家好,我是程序猿追,众所周知算法是比较复杂又基础的学科,每个学编程的人都会学习大量的算法。无论在我们面试还是笔试算法是必不可少的,我们打开某招聘网站,发现薪资待遇都很友好。
再看看某大厂的面试题
无论是找工作,还是打比赛,搞科研,算法占据了主要地位,在我刚开始学习算法时(我还是一个小菜鸡时),我的一个大牛学长(已经拿到了心仪的 offer)推荐我一个神奇的神奇——我是神奇,里面大厂的算法题、面试题以及面经应有尽有,我们来看看吧。
反转链表
?描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0 ≤ n ≤ 1000
要求:空间复杂度 O(1),时间复杂度 O(n)。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
?示例1
输入:{1,2,3}
返回值:{3,2,1}
?示例2
输入:{}
返回值:{}
说明:空链表则输出空
题解代码
public class Solution { public ListNode ReverseList(ListNode head) { //处理空链表 fast-template if (head == null) return null; ListNode cur = head; ListNode pre = null; while (cur != null) { //断开链表,要记录后续一个 ListNode temp = cur.next; //当前的next指向前一个 cur.next = pre; //前一个更新为当前 pre = cur; //当前更新为刚刚记录的后一个 cur = temp; } return pre;}}
链表内指定区间反转
?描述
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 NULL1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 NULL1→4→3→2→5→NULL.
数据范围: 链表长度 0 < size ≤ 1000,0 < size0 < m ≤ n ≤ size,链表中每个节点的值满足 ∣val∣≤1000
要求:时间复杂度 O(n) ,空间复杂度 O(n)
进阶:时间复杂度 O(n),空间复杂度 O(1)
?示例1
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}
?示例2
输入:{5},1,1
返回值:{5}
题解代码
import java.util.*;public class Solution { public ListNode reverseBetween (ListNode head, int m, int n) { //加个表头 fast-template ListNode res = new ListNode(-1); res.next = head; //前序节点 ListNode pre = res; //当前节点 ListNode cur = head; //找到m for (int i = 1; i < m; i++) { pre = cur; cur = cur.next; } //从m反转到n for (int i = m; i < n; i++) { ListNode temp = cur.next; cur.next = temp.next; temp.next = pre.next; pre.next = temp; } //返回去掉表头 return res.next;}}
链表的奇偶重排
?描述
给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。
注意是节点的编号而非节点的数值。
数据范围:节点数量满足 0 ≤ n ≤ 10^5,节点中的值都满足 0 ≤ val ≤ 1000
要求:空间复杂度 O(n),时间复杂度 O(n)
?示例1
输入:{1,2,3,4,5,6}
返回值:{1,3,5,2,4,6}
?说明:
1->2->3->4->5->6->NULL
重排后为
1->3->5->2->4->6->NULL
?示例2
输入:{1,4,6,3,7}
返回值:{1,6,7,4,3}
?说明:
1->4->6->3->7->NULL
重排后为
1->6->7->4->3->NULL
奇数位节点有1,6,7,偶数位节点有4,3。重排后为1,6,7,4,3
?备注:
链表长度不大于200000。每个数范围均在int内。
题解代码
import java.util.*;public class Solution { public ListNode oddEvenList (ListNode head) { //如果链表为空,不用重排 fast-template if(head == null) return head; //even开头指向第二个节点,可能为空 ListNode even = head.next; //odd开头指向第一个节点 ListNode odd = head; //指向even开头 ListNode evenhead = even; while(even != null && even.next != null){ //odd连接even的后一个,即奇数位 odd.next = even.next; //odd进入后一个奇数位 odd = odd.next; //even连接后一个奇数的后一位,即偶数位 even.next = odd.next; //even进入后一个偶数位 even = even.next; } //even整体接在odd后面 odd.next = evenhead; return head;}}
链表中的节点每k个一组翻转
?描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
数据范围: 0 ≤ n ≤ 2000 , 1 ≤ k ≤ 2000 ,链表中每个元素都满足 0 ≤ val ≤ 1000
要求空间复杂度 O(1),时间复杂度 O(n)
?例如:
给定的链表是 1→2→3→4→5
对于 k = 2, 你应该返回 2→1→4→3→5
对于 k = 3, 你应该返回 3→2→1→4→5
?示例1
输入:{1,2,3,4,5},2
返回值:{2,1,4,3,5}
?示例2
输入:{},1
复制返回值:{}
import java.util.*;public class Solution { public ListNode reverseKGroup (ListNode head, int k) { //找到每次翻转的尾部 fast-template ListNode tail = head; //遍历k次到尾部 for (int i = 0; i < k; i++) { //如果不足k到了链表尾,直接返回,不翻转 if (tail == null) return head; tail = tail.next; } //翻转时需要的前序和当前节点 ListNode pre = null; ListNode cur = head; //在到达当前段尾节点前 while (cur != tail) { //翻转 ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } //当前尾指向下一段要翻转的链表 head.next = reverseKGroup(tail, k); return pre;}}
不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!