链表:
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域
链表的初始化:
public class ListNode{
int val;
List next;
public ListNode(){
}
public ListNode(int val){
this.val = val;
}
public ListNode(int val,ListNode next){
this.val =val;
this.next = next;
}
}
为什么需要无参构造器:子类继承父类的时候会自动继承父类的默认构造函数,如果没有无参构造器,子类继承就会报错.
链表的指向问题:
如果放在左边就表示是自己的指向,如果放在右边就表示是它的下一个节点。
node.next = head.next; //node结点指向head的下一个节点
class ListNode{
int val;
ListNode next;
public ListNode(){};
public ListNode(int val){
this.val = val;
}
public ListNode(int val,ListNode next){
this.val = val;
this.next =next;
}
}
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if(index>=size || index < 0){
return -1;
}
ListNode currentNode = head;
for(int i=0; i <= index ;i++){
currentNode = currentNode.next;
}
return currentNode.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;
}
if(index < 0){
index = 0;
}
ListNode pred = head;
for(int i = 0; i<index; i++){
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
size++;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >=size){
return;
}
size--;
if(index ==0){
head =head.next;
return;
}
ListNode pred = head;
for(int i = 0; i < index; i++){
pred = pred.next;
}
pred.next = pred.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);
*/
虚拟头节点方便操作整个链表,也就是对头节点以及头节点后续节点都能够一视同仁,方便执行插入,删除操作, ListNode dummy = new ListNode(0); dummy.next = head;
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
递归:
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) return head;
head.next = removeElements(head.next , val);
return head.val == val ? head.next : head;
}
}
直接删除:
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null) return head;
while(head != null && head.val == val ){
head = head.next;
if(head == null){
return null;
}
}
ListNode temp = head;
while(temp.next != null){
if(temp.next.val == val){
temp.next = temp.next.next;
}else{
temp = temp.next;
}
}
return head;
}
}
这里如果用虚拟头节点会更好,不需要单独考虑头结点的情况:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while (temp.next != null) {
if (temp.next.val == val) {
temp.next = temp.next.next;
} else {
temp = temp.next;
}
}
return dummyHead.next;
}
}
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cru = head;
while(cru != null){
ListNode tempnext = cru.next;
cru.next = pre;
pre =cru;
cru = tempnext;
}
return pre;
}
}
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur.next 节点用tmp指针保存一下,也就是保存一下这个节点。
接着移动pre 和cru节点就解决了,简单题还是比较容易想到的