> 文档中心 > 链表的使用(1)

链表的使用(1)

上一篇说过会找一些OJ题目来看看单链表的使用,题目挺多,计划分成两篇

目录

1.反转单链表

2.链表中间节点

 3.链表的倒数第k个节点

4.合并两个有序链表

 5.链表的回文结构


1.反转单链表

思路

上一篇写的单链表里面讲过怎么实现头插法,而这里的反转链表就是将头节点后面的节点依次放到前面来 ,因为需要进行多次头插,所以需要另外一个节点来记录当前头插的节点的下一个节点

代码如下:

class Solution {    public ListNode reverseList(ListNode head) { if(head==null) {     return null; } if(head.next==null) {     return head; } //链表为null或者只有一个节点的情况下不需要进行反转  ListNode add=head.next;  head.next=null;  //原来的头节点反转之后就是最后一个节点,地址需要指向null while(add!=null) {     ListNode addNext=add.next;     add.next=head;     head=add;     add=addNext; } return head;    }}

2.链表中间节点

思路:

题目中有说明head是非空单链表,所以head为null的情况就不需要判断了

主要思路就是快慢指针

新建两个节点fast和slow,fast每次走两步,slow每次走一步,来看看奇数个以及偶数个节点下二者的情况

奇数个:

当fast走到最后一个节点的时候slow恰好在中间节点

偶数个 :

fast为null的时候slow正好在第二个中间节点 

代码如下:

class Solution {    public ListNode middleNode(ListNode head) { if(head.next==null) {     return head; } ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null) {     slow=slow.next;     fast=fast.next.next; } return slow;    }}

 

 3.链表的倒数第k个节点

 思路:

依旧是快慢指针

让fast和slow之间的距离为k,当fast为null的时候slow的位置就是我们要找的节点,如下图(以找倒数第二个节点为例)

或者二者之间相差k-1,fast到最后一个节点的时候slow也是我们要找的节点

 

代码如下:

class Solution {    public ListNode getKthFromEnd(ListNode head, int k) { //首先需要判断k的值是否合法  if(k0) {  //先让fast走k-1步,然后二者同步向后移动     fast=fast.next;     if(fast==null) {  return null;     }     --k; } while(fast.next!=null) {     fast=fast.next;     slow=slow.next; } return slow;    }}

 

4.合并两个有序链表

 思路:

如果是数组的话很简单:新建一个数组,原来的两个数组的元素进行比较,较小的那个放在新数组中

这里的链表也是这个思路

新建一个头节点,原来的两个链表的节点进行比较,较小的那个接在这个新链表的尾部即可

还有一点就是要考虑两个链表长度不一样的情况

代码如下:

class Solution {    public ListNode mergeTwoLists(ListNode list1, ListNode list2) { ListNode head=new ListNode(); ListNode tmp=head; if(list1==null && list2!=null) {     return list2; }  if(list2==null && list1!=null) {     return list1; }  while(list1!=null && list2!=null) {     if(list1.val<list2.val) {  tmp.next=list1;  list1=list1.next;  tmp=tmp.next;     } else {  tmp.next=list2;  list2=list2.next;  tmp=tmp.next;     } } if(list1==null) {     tmp.next=list2; } else {     tmp.next=list1; } return head.next;    }}

 5.链表的回文结构

思路:

原链表如图:

 

我们需要将其变成下面的形式才便于进行判断

 那么接下来的问题就是如何变了

我们需要找到链表的中间节点,然后从中间节点向后直到末尾的节点进行反转

代码如下:

class Solution {    public boolean isPalindrome(ListNode head) { if(head==null || head.next==null) {     return true; } ListNode fast=head; ListNode slow=head; //找中间节点 while(fast!=null && fast.next!=null) {     slow=slow.next;     fast=fast.next.next; } //反转后面的节点,反转完毕后slow就是右边链表的头结点 ListNode add=slow.next; slow.next=null; while(add!=null) {     ListNode addNext=add.next;     add.next=slow;     slow=add;     add=addNext; } //判断是否回文 while(slow!=head && head.next!=null) {     if(slow.val!=head.val) {  return false;     }     slow=slow.next;     head=head.next; } return true;    }}

 

链表的题目暂时就先到这,完

链表的使用(1) 2022深度学习开发者峰会 链表的使用(1) 5月20日13:00让我们相聚云端,共襄盛会!美国云服务器