代码随想录第十二期集训营-第三天
今天是营中第三天训练日,内容包括链表的基础知识,力扣203、707以及206.
203.移除链表元素
删除链表元素时,要删除head和非head节点是两种操作。删除head时,直接让head = head.next、删除非head时,要让被删节点cur的前一个节点pre指向cur.next,也就是pre.next.next = cur.next。为了能统一操作,我们就采用虚拟头结点这种方式,创建一个虚拟头结点,让他指向原来的head,然后对原链表操作,这样就能统一删除操作,返回时返回虚拟头结点的下一个节点。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeElements(ListNode head, int val) { if(head == null){ return null; } ListNode dummyNode = new ListNode(-1,head); ListNode cur = dummyNode; while(cur.next != null){ if(cur.next.val == val){ cur.next = cur.next.next; }else{ cur = cur.next; } } return dummyNode.next; } }
另一种用双指针的思想,一个指针cur负责遍历链表找到删除元素,另一个指针pre负责删除。
class Solution { public ListNode removeElements(ListNode head, int val) { if(head == null){ return null; } ListNode dummyNode = new ListNode(-1,head); ListNode cur = head; ListNode pre = dummyNode; while(cur != null){ if(cur.val == val){ pre.next = cur.next; }else{ pre = cur; } cur = cur.next; } return dummyNode.next; } }
707.设计链表
这题就是设计链表中的方法,都用虚拟头结点做就行。
206.反转链表
经典题,我看一些面试手撕都有这个。
第一种方法我用双指针,第二种是递归,正向递归,思想和双指针一样,都是一个指针,一个cur指向当前节点,一个pre为cur前一个节点。注意的是反转之前要有一个临时节点变量,负责记录cur.next,要不然反转之后找不到下一个节点了。
class Solution { public ListNode reverseList(ListNode head) { if(head == null){ return null; } ListNode cur = head; ListNode pre = null; while(cur != null){ ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; } }
正向递归有意思的就是递归方法的返回值中的传参,要找对pre和cur。正向递归其实就是用递归方法代替了双指针中的while循环。
class Solution { public ListNode reverseList(ListNode head) { return reverse(null,head); } public ListNode reverse(ListNode pre,ListNode cur){ //判断cur是否为空,为空要么是原来就是空,要么就是遍历到结尾了 if(cur == null){ return pre; } //临时节点记录当前节点的下一个节点 ListNode temp = cur.next; //反转 cur.next = pre; //返回时,还是要找到前一个节点和当前节点,前一个节点就是此时的cur,当前节点就是此时的temp return reverse(cur,temp); } }
还有一种方法为反向递归,需要通过递归找到最后一个节点,然后反转,最后返回最后一个节点。
class Solution { public ListNode reverseList(ListNode head) { //从后向前递归,找到最后一个节点,从后向前反转 //边界条件 if(head == null){ return null; } //找到最后一个节点 if(head.next == null){ return head; } //去找最后一个节点 ListNode last = reverseList(head.next); //此时的head是last的前一个节点,开始反转 head.next.next = head; head.next = null; return last; } }
第三天打卡结束,其实是补卡
#23届找工作求助阵地##我的实习求职记录##你们的毕业论文什么进度了#