203.移除链表元素
题目
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例1
输入:输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例2
输入:head = [], val = 1
输出:[]
解题思路
加入他是个LIst,你怎么操作,遍历,对比,对比,然后删除操作,对吧?
其实链表也一样,只是你一时想不起链表怎么遍历而已
那我现在告诉你链表的遍历模版是
while(cur!=null){
cur = cur.next;
}
有思路了吗?我们再给链表加一个前驱的空节点。保持处理逻辑是一致
1、定义空节点
2、前驱指针指向空节点
3、当前指针指向当前节点(遍历用)
4、遍历链表
代码实现
public ListNode removeNode(ListNode head,int value){
//空节点
ListNode dummy =new ListNode(-1,head);
//前驱指针
ListNode pre = dummy;
//当前节点指正,遍历链表用
ListNode cur = head;
while(cur!=null){
if(cur.value== value){
pre.next = cur.next;
}else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
707.设计链表
题目
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0
示例
输入
[“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出
[null, null, null, null, 2, null, 3]
解释
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
myLinkedList.get(1); // 返回 2
myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
myLinkedList.get(1); // 返回 3
思路
这个不算算法,就是练习列表操作,直接上代码
代码实现
class MyLinkedList {
/**
* 定义属性 链表长度
* 链表节点
*/
private int size = 0;
private ListNode head;
public MyLinkedList() {
this.size = 0;
this.head = new ListNode(0);
}
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode currentNode = head;
//包含一个虚拟头节点,所以查找第 index+1 个节点
for (int i = 0; i <= index; i++) {
currentNode = currentNode.next;
}
return currentNode.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if(index>size){
return;
}
if(index<0){
index =0;
}
ListNode pre = head;
for(int i=0; i<index; i++){
pre = pre.next;
}
ListNode newNode =new ListNode(val);
newNode.next = pre.next;
pre.next = newNode;
size++;
}
public void deleteAtIndex(int index) {
if(index<0||index>=size){
return;
}
if(index==0){
head = head.next;
return;
}
ListNode pre = head;
for(int i=0; i<index;i++){
pre = pre.next;
}
pre.next = pre.next.next;
size--;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
206.反转链表
这是一道非常经典的题目了
题目
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
思路
解法一 :遍历链表
public ListNode reversal(ListNode head) {
//前驱节点
ListNode prev = null;
//当前节点
ListNode curr = head;
//临时节点
ListNode temp = null;
//遍历链表
while (curr!=null){
//临时保存后继
temp = curr.next;
//反转
curr.next = prev;
//前驱指针前进
prev = curr;
//当前节点前进
curr = temp;
}
return prev;
}
解法二 :递归1
//临时保存下一个节点
ListNode temp = curr.next;
//反转
curr.next = prev;
if(curr == null){
return prev;
}
代码实现
public ListNode reversalRecursion(ListNode head){
//从第一队开始
return reverse(null,head);
}
private ListNode reverse(ListNode prev, ListNode curr) {
if(curr == null){
return prev;
}
//临时保存下一个节点
ListNode temp = curr.next;
//反转
curr.next = prev;
//开始下一对
return reverse(curr,temp);
}
解法三 递归2
递归解题三部曲:
head.next.next = head;
head.next = null
if(head ==null || head.next ==null){
return head;
}
整体代码实现
public ListNode reverseListNode(ListNode head){
if(head == null || head.next ==null){
return head;
}
ListNode result = reverseListNode(head.next);
head.next.next = head;
head.next = null;
return result;
}