203. 移除链表元素
击败50%
思路
创建一个虚拟头节点phead,将链表的头结点head指向该头节点,接着以head为参考值去遍历整个链表,如何当前指向的节点的下一个节点的值正好等于目标值,则将该节点链接至下下个节点(即删除目标节点),当前指针仍然指向该节点,否则指针后移,继续遍历链表。
但是可能因为new了一个新节点,时间上花费比较多。
/**
* 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;
}
else{
ListNode phead = new ListNode();
phead.next = head;
head = phead;
while(head.next!=null){
ListNode next = head.next;
if(next.val==val){
head.next = next.next;
}
else{
head = head.next;
}
}
return phead.next;
}
}
}
优质题解
递归
递归的条件要特别注意。
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head==null){
return null;
}
else{
head.next=removeElements(head.next,val);
if(head.val==val){
return head.next;
}
else{
return head;
}
}
}
}
707. 设计链表
A了一个世纪
思路
其实应该算是链表的一些常规操作,一直错一直错,但找不到错误.jpg,裂开了。第二天在项目交流会上一直查一直查,查不出来,干脆重写一遍,结果过了,然后对照代码,发现for循环的一个结束条件写错了(下面被注释的)。说明查不出来错误的时候重写写一遍也是有效的。
class MyLinkedList {
int size;
ListNode iHead;
ListNode cur;
public MyLinkedList() {
size = 0;
iHead = new ListNode(-2);
cur = iHead;
}
public int get(int index) {
cur = iHead;
if(index>=0 && index<size){
while(index>=0){
cur = cur.next;
index--;
}
return cur.val;
}
else{
return -1;
}
}
public void addAtHead(int val) {
size++;
ListNode node = new ListNode(val);
node.next = iHead.next;
iHead.next = node;
}
public void addAtTail(int val) {
size++;
ListNode node = new ListNode(val);
cur = iHead;
while (cur.next!=null) {
cur = cur.next;
}
cur.next = node;
}
public void addAtIndex(int index, int val) {
if(index>=0 && index<=size){
ListNode node = new ListNode(val);
cur = iHead;
size++;
for(int i=0; i<index; i++){
cur = cur.next;
}
node.next = cur.next;
cur.next = node;
}
else{
return;
}
}
public void deleteAtIndex(int index) {
if(index>=0 && index<size){
size--;
cur = iHead;
for(int i=0; i<index; i++){
cur = cur.next;
}
cur.next = cur.next.next;
}
else{
return;
}
}
// public void deleteAtIndex(int index) {
// head = iHead;
// if(index<0 || index>size-1){
// return;
// }
// else{
// for(int i=0; i<index-1; i++){
// head = head.next;
// }
// head.next = head.next.next;
// size--;
// }
// }
}
class ListNode{
int val;
ListNode next;
public ListNode(){};
public ListNode(int val){
this.val = val;
}
}
206. 反转链表
AC
思路
利用双指针的思路,两个指针分别指向相邻的前后两个节点,不断向右滑动,直到没有元素时结束。但是要特别注意一个事情:要把头指针原本的next属性的值改为null !!
其实也可以不用定义虚拟头节点,两个指针分别指向头节点和头节点的下一个节点,但也要接的改掉原本头指针的next属性,否则会报如下错误,原因是出现了链表回环。
自己写的递归算法不是很好,运行时间很长。并且为了改掉原本头节点的next指针,又重新遍历了一遍链表。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode iHead = new ListNode();
ListNode prev = iHead;
if(head==null){
return null;
}
else{
while(head!=null){
ListNode tmp = head.next;
if(prev==iHead){
head.next = null;
}
else{
head.next = prev;
}
prev = head;
head = tmp;
}
return prev;
}
}
}
// /**
// * 递归解法
// */
// class Solution {
// public ListNode reverseList(ListNode head) {
// if(head==null){
// return null;
// }
// else{
// if(head.next!=null){
// ListNode tmp = reverseList(head.next);
// ListNode cur = tmp;
// head.next = null;
// while(cur.next!=null){
// cur = cur.next;
// }
// cur.next = head;
// return tmp;
// }
// else{
// return head;
// }
// }
// }
// }