移除链表元素
题目链接:
解题思路:
由于删除链表中的某个元素,就需要找到这个元素的前驱节点,而链表的头结点是没有前驱节点的,这就导致移除链表中头结点的操作和移除其他节点的操作是不同。在这里,本题的解法采用创建一个虚拟的头结点,使得对原本头结点的操作和其余节点的操作是相同的。
代码实现:
/**
* 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 head;
ListNode temp = new ListNode(-1,head); //创建一个虚拟的头结点
ListNode pre = temp; //使pre指向这个虚拟的头结点
ListNode cur = head; //使cur指向原先的头结点(始终保持pre和cur相邻)
while(cur !=null){
if(cur.val == val){
pre.next = cur.next;
}
else{
pre = cur;
}
cur = cur.next;
}
return temp.next;
}
}
总结:
要充分熟悉对链表中结点的移除的操作。
设计链表
题目链接:
代码实现:
class ListNode{
int val;
ListNode next;
ListNode(){}
ListNode(int val){
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
int size = 0;
head = new ListNode(0);
}
public int get(int index) {
if (index <0 || index >= size)
return -1;
ListNode cur = head;
for (int i = 0;i <= index;i++) {
cur = cur.next;
}
return cur.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 ;
ListNode cur = head;
if (index < 0) {
index = 0;
}
ListNode pre = head;
ListNode toadd = new ListNode(val);
for(int i = 0; i < index; i++) {
pre = pre.next;
}
toadd.next = pre.next;
pre.next = toadd;
size++;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >=size)
return ;
size--;
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;
}
}
/**
* 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);
*/
总结:
要充分熟悉对链表的增删查改等操作,并熟知每一种操作的时间复杂度。
反转链表
题目链接:
解题思路:
可以利用递归和双指针法来进行操作,本题采用双指针的方法来进行实现。只要改变链表的指向即可实现此操作,将每个节点的指向全部反转即可。
代码实现:
/**
* 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 reverseList(ListNode head) {
ListNode temp = null;
ListNode pre = null;
ListNode cur = head;
while(cur != null) {
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
总结:
利用一个临时变量来保存cur的下一个结点是解题的关键。