Leetcode 203:
https://leetcode.com/problems/remove-linked-list-elements/description/
题目的第一想法:
单向链表的删除情况分为首中2种。在首的情况下,需要一直删除首位node,变更head指向的位置。在中的情况下我们需要一个pre来跟踪前一位Node,做pre指向current.next。同时需要注意的是在链表的size可以为0。于是就有三种情况需要被解决:1,当链表的本身size为0;2,当链表头部的node需要被删除;3,当链表头部的node被删除后依旧有更多的(>=2)的node可以被遍历。当完成这三步时,这个问题便可以被解决。
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null){//when size == 0
return null;
}
while(head != null && head.val == val){// removing the head node
ListNode temp = head.next;
head.next = null;
head = temp;
}
if(head != null && head.next != null){// if there is still more nodes to traverse
ListNode pre = head;
ListNode current = head.next;
while(current != null){
if(current.val == val){// if a node is found to be deleted
pre.next = current.next;
current = current.next;
}else{
pre = current;// traverse
current = current.next;
}
}
}
return head;
}
}
Leetcode 707:
https://leetcode.com/problems/design-linked-list/description/
题目的第一想法:
这是道考验基本功的题,如果对于链表的数据结构比较熟悉的话做出这道题就没什么大问题。我的第一想法是最一个双向链表,这样的话对删除Node的操作会比较友好。但在增加Node上增添了很多麻烦。还有一点是应该增加Sentinel Node,这样的话对与整体的写法会简洁方便许多。但我的初想法因为对sentinel node的下意识恐惧就没有加上,导致之后在debug上费了不少时间。以下是我的第一版通过的code。时间复杂度不好,具体原因等我研究一下再更新。
class ListNode {
public int val;
public ListNode next;
public ListNode pre;
public ListNode(int val){
this.val = val;
next = null;
pre = null;
}
}
class MyLinkedList {
ListNode head;
ListNode tail;
int size;
public MyLinkedList() {
head = null;
tail = null;
int size = 0;
}
public int get(int index) {
ListNode current = head;
if(index >= size){
return -1;
}
for(int i = 0; i < index; i++){
current = current.next;
}
return current.val;
}
public void addAtHead(int val) {
ListNode temp = new ListNode(val);
temp.next = head;
temp.pre = null;
if(size != 0){
head.pre = temp;
}else{
tail = temp;
}
head = temp;
size++;
}
public void addAtTail(int val) {
ListNode temp = new ListNode(val);
temp.pre = tail;
if(size != 0){
tail.next = temp;
}else{
head = temp;
}
tail = temp;
size++;
}
public void addAtIndex(int index, int val) {
System.out.println(index + " " + val);
if(index <= size){
if(size == 0){
ListNode temp = new ListNode(val);
head = temp;
tail = temp;
size++;
}else if(index == size){
this.addAtTail(val);
}else if(index == 0){
this.addAtHead(val);
}else{
ListNode current = head;
for(int i = 0; i < index; i++){
current = current.next;
}
ListNode temp = new ListNode(val);
System.out.println(current.val);
temp.next = current;
temp.pre = current.pre;
current.pre.next = temp;
current.pre = temp;
size++;
}
}
}
public void deleteAtIndex(int index) {
if(index < size){
ListNode current = head;
if(index == 0){
ListNode temp = current.next;
if(size == 1){
head = null;
}else{
temp.pre = null;
current.next = null;
head = temp;
}
}else if(index == size - 1){
ListNode temp = tail.pre;
tail.pre = null;
temp.next = null;
tail = temp;
}else{
for(int i = 0; i < index; i++){
current = current.next;
}
ListNode temp = current.pre;
temp.next = current.next;
current.next.pre = temp;
}
size--;
}
}
}
Leetcode 206:
https://leetcode.com/problems/reverse-linked-list/description/
题目的第一想法:
这道题和删除的根本思想差不多,都是依靠pre和current做一个遍历来更改链表的方向。需要注意的是current和pre变更的循序。需先改pre为current再改current为temp(current.next)。除此之外,这道题观感上也应可以那recurssion来解决。等我有时间再尝试下新的解法。
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode current = head.next;
ListNode pre = head;
pre.next = null;
while(current != null){
ListNode temp = current.next;
current.next = pre;
pre = current;
current = temp;
}
head = pre;
return head;
}
}
看完代码随想录之后的想法:
。。。
自己实现过程中遇到哪些困难:
这道题倒是没遇到什么特别的困难
今日收获,记录一下自己的学习时长:
复习了链表的相关操作和知识。明天需要再把python版本的答案附写一遍,来熟悉python语法