关于链表
- 链表由不同结点连接而成,每个结点包括一个指针域和一个数据域,指针域用于存放指向下一个结点的指针,数据域用于存放当前结点的值(可以是基本类型的值,也可以是引用类型的值)
- 链表分类:
1)单链表
2)双向链表
3)环形链表
Leecode题型
单链表
1. 面试题02.03
1)题目:
2)分析
由于要删除指定结点c,因此只要将c的后一个结点移到c的位置即可
3)实现
/** * Definition for singly-linked list.
* public class ListNode {
* * int val;
* ListNode next;
* * ListNode(int x){
* val = x;
* }
* *} */
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
4)解释
例如:a->b->c->d->e->f,删除c
先将c后一位的值赋给c,即a->b->d->d->e->f
再删除原来c的后一位(d),即a->b->d【->d】->e->f
2. 237. 删除链表中的节点
1)题目
2)分析
与上一题相似,若要删除5结点,则先把5结点的下一节点1的值复制给5结点,再将1结点删除
3)代码
与上一题相似
3. 删除单链表中给定数值的节点
1)题目
2)分析
这题和前两题不一样,前两题是直接给要删除的那个【节点】,这题是给值,因此还要判断节点的值和给的值是否相同,相同才进行删除。
由于要返回删除后链表的头节点,因此使用dummyHead解题
解题步骤如下:
a)定义一个dummyHead,使dummyHead.next = head,再定义一个指向dummyHead的节点cur
b)判断cur,只要cur不为空并且cur.next也不为空,则进行值是否相等的判断
这里注意:由于cur指向的是dummyHead,因此真正传入的第一个节点其实是cur.next
c)进入判断,只要cur.next.val等于给定的值,则删除cur.next,否则cur后移,进行下一节点的判断
d)返回dummyHead.next
3)代码
class Solution {
public ListNode deleteNode(ListNode head, int val) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode cur = dummyHead;
while(cur != null && cur.next != null){
if(cur.next.val == val){
cur.next = cur.next.next;
break;
}
cur = cur.next;
}
return dummyHead.next;
4. 删除排序链表中重复的元素
1)题目
2)分析
首先先判断传入的head是否为空,若为空则返回null
接着定义一个cur指向head
判断cur和cur.next是否为空
都不为空:判断cur的值和cur的下一个值是否相等,若相等则把cur的下一个的下一个值赋给cur,若不相等则cur后移
进行下一次循环
返回head
3)代码
5. 面试题02.01
1)待更
6. 面试题18. 删除链表的节点
- 题目
2)分析
定义一个哑节点dummyHead,将dummyHead的hext域指向head
再定义一个节点cur指向当前节点
循环判断,如果当前节点的下一个节点的值等于当前节点的值,则删除当前节点的下一个节点
否则当前节点后移 - 代码
7. 面试题02.06 回文链表
1) 题目
2)分析
由于是回文链表,首先想到利用栈结构,
定义两个节点指向head,利用一个节点将元素全部入栈
再利用一个节点接收出栈的元素
判断两个元素是否相等
3)代码
4)总结
但是这种方法的时间复杂度和空间复杂度都很高,得优化
快慢指针
1. 面试题22
1)题目
2)分析
要删除倒数第k个结点,只要先将快指针走到第k个结点,然后再将快慢指针一起前进,最终慢指针指向的即为倒数第k个结点
3)实现
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
for(int i = 0;i < k;i++){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
2. 面试题02.02
1)题目
2)分析
与上一题类似,也是返回倒数第k个节点,采用快慢指针进行解决
3)代码与上一题一样,这里省略
3. 链表中间结点
1)题目:
2)分析
定义两个指针,快指针每次走两步,慢指针每次走一步,最后慢指针指向的即为中间节点
3)实现
class Solution {
public ListNode middleNode(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
4. 环形链表
1)题目
2)分析
同样利用快慢指针进行解题,快指针每次走两步,慢指针每次走一步,进行判断,如果值相等则返回true
3) 代码
反转链表
1. 面试题24
1)题目
2)分析
单链表反转
可以采用单链表反转的方式,定义一个dummyHead,将dummyHead置空,再定义一个指向当前节点的指针cur,令cur指向head,在整个过程中对curt进行判断,只要不为空,就进行反转操作。
具体的反转操作:
a) 定义一个临时节点temp,用于存放cur的下一个节点
b) 进行反转,将cur的next域指向dummyHead
c) 将dummyHead后移至cur
d) 将temp的值赋给cur,处理下一节点
3)代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode dummyHead = null;
ListNode cur = head;
while(cur != null){
ListNode temp = cur.next;
cur.next = dummyHead;
dummyHead = cur;
cur = temp;
}
return dummyHead;
}
头插法(待更)
2)分析
定义一个新的头节点