代码随想录算法训练营第3天| leetcode 203.移除链表元素 , 707.设计链表 ,206.反转链表

  1. 移除链表元素

题目链接: 203. 移除链表元素 - 力扣(LeetCode)

解题思路:

要设置虚拟头结点,这样如果移除的结点是头结点head,包括后序对链表的操作,都可以对所有的结点一视同仁,也不用分类讨论( 该节点是否是头结点).

接下来声明两个遍历ListNode pre和 curr,初始值为 dummy 和head.

遍历链表,遇到结点值等于 目标值val的时候,让该节点的前一个结点pre的指针指向 当前结点的下一个结点 pre.next=curr.next.

最后返回dummy 的下一个结点 ( 就是头结点 ),而不是head,head也可能被删除掉.

答案:

class Solution {

public ListNode removeElements(ListNode head, int val) {

ListNode dummy=new ListNode(-1,head) ;

ListNode pre=dummy;

ListNode curr=head;

while (curr!=null ){

if (curr.val==val){

pre.next=curr.next;

}else {

pre=curr;

}

curr=curr.next;

}

return dummy.next;

}

}

● 707.设计链表

题目链接: 707. 设计链表 - 力扣(LeetCode)

解题思路:

需要自己创建一个单向链表 或者双向链表对象. 本答案为 单向链表.

对链表进行初始化,size这块的设置没有想到. 包括后面增加和删除的时候,分别size++ 和size--.都没有考虑到. 还要初始化虚拟头结点dummy.

get(index):

获取元素是比较容易的. 遍历到index位置处,返回对应值.

addAtIndex(index,val):

添加元素的时候,容易出错.

遍历到索引等于index 的结点的前一个结点 pre.

先让新增结点 listNode ( 值为val ) 指向 pre的下一个结点. 再让pre指向 新增结点 listNode.

ListNode listNode = new ListNode(val);

listNode.next=pre.next;

pre.next=listNode;

deleteAtIndex(index):

pre.next= pre.next.next;

遍历到索引等于index 的前一个位置, 让前一个位置pre 的指针指向 索引等于 index的位置的结点 pre.next 的下一个结点,就完成了删除.

参考答案:

class ListNode {

ListNode next;

int val;

public ListNode() {

}

public ListNode( int value,ListNode next) {

this.next = next;

this.val = value;

}

public ListNode(int value) {

this.val = value;

}

}

class MyLinkedList {

// 链表长度 和 虚拟头结点

private int size;

private ListNode dummy;

public MyLinkedList() {

dummy = new ListNode(-1);

size = 0;

}

public int get(int index) {

if (index >= size || index < 0) {

return -1;

}

ListNode pre = dummy;

for (int i = 0; i <= index; i++) {

pre = pre.next;

}

return pre.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 < 0) {

index = 0;

}

if (index > size) {

return;

}

size++;

ListNode pre = dummy;

for (int i = 0; i <index; i++) {

pre = pre.next;

}

ListNode listNode = new ListNode(val);

listNode.next=pre.next;

pre.next=listNode;

}

public void deleteAtIndex(int index) {

if (index >= size || size < 0) {

return ;

}

size--;

ListNode pre = dummy;

for (int i = 0; i < index; i++) {

pre = pre.next;

}

pre.next= pre.next.next;

}

}

● 206.反转链表

题目链接: https://leetcode.cn/problems/reverse-linked-list/

解题思路:

此题不能设置虚拟头结点,否则反转之后,链表多了一个结点.

通过设置三个结点来实现, ListNode pre ; curr ; temp

ListNode pre = null;

ListNode curr = head;

ListNode temp = null;

循环内容:

tem结点用来临时存储 curr,next;

完成curr和 pre的指针反向关系. curr.next=pre; (curr左指向右,变成右指向左.)

接下来, pre和 curr各向前移动一个位置.

pre=curr;

curr=temp;

while循环结束,返回的头结点head 是谁呢? curr为null的时候,遍历到链表的尾部了,不能for循环了,所以返回的是curr的前一位 pre.

参考答案:

class Solution {

public ListNode reverseList(ListNode head) {

if (head == null) {

return null;

}

ListNode pre = null;

ListNode curr = head;

ListNode temp = null;

while (curr != null) {

temp = curr.next;

curr.next=pre;

pre=curr;

curr=temp;

}

return pre;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值