链表
设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。
代码实现为:
/**
* 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) {
//可能删除头结点,故需要设置dummy节点
ListNode dummy = new ListNode(-1,head);
ListNode pre = dummy;
ListNode cur = head;
while(cur!=null){
if(cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
双向链表比单向链表多个属性prev,指向上一个节点
代码实现为:
class ListNode{
//双向链表
int val;
ListNode next,prev;
public ListNode(){}
public ListNode(int val){
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head,tail;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
tail = new ListNode(0);
head.next = tail;
tail.prev = head;
}
public int get(int index) {
if(index<0 || index>=size){
return -1;
}
ListNode cur;
//判断哪一边遍历时间更短
if(index>size/2){
//从tail开始
cur = tail;
for(int i = 0;i<size-index;i++){
cur = cur.prev;
}
}else{
//从head开始
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 || index<0){
return;
}
size++;
//找到前驱
ListNode pre = head;
for(int i =0;i<index;i++){
pre = pre.next;
}
ListNode add = new ListNode(val);
add.next = pre.next;
pre.next.prev = add;
add.prev = pre;
pre.next = add;
}
public void deleteAtIndex(int index) {
if(index>=size || index<0){
return;
}
size--;
ListNode pre = head;
for(int i =0;i<index;i++){
pre = pre.next;
}
pre.next.next.prev = pre;
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);
*/
双指针法,定义一个pre指针,一个cur指针
代码实现为:
/**
* 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 pre = null;
ListNode cur = head;
ListNode tmp = null;
while(cur!=null){
tmp = cur.next;
cur.next = pre;
//先移动pre,再移动cur
pre = cur;
cur = tmp;
}
return pre;
}
}
代码实现为:
/**
* 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 swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
while(cur.next!=null && cur.next.next!=null){
ListNode n1 = cur.next;
ListNode n2 = cur.next.next;
cur.next = n2;
n1.next = n2.next;
n2.next = n1;
cur = cur.next.next;
}
return dummy.next;
}
}
双指针(快慢指针)
快慢指针相差n个节点
代码实现为:
/**
* 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 removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1,head);
ListNode slowIndex = dummy;
ListNode fastIndex = dummy;
//快慢指针相差n个节点
for(int i =0;i<=n;i++){
fastIndex = fastIndex.next;
}
while(fastIndex!=null){
fastIndex = fastIndex.next;
slowIndex = slowIndex.next;
}
//此时slowIndex在待删除元素前一个位置
slowIndex.next = slowIndex.next.next;
return dummy.next;
}
}
代码实现为:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pA = headA,pB = headB;
while(pA!=pB){
pA = pA==null?headB:pA.next;
pB = pB==null?headA:pB.next;
}
return pA;
}
}
利用HashSet存放节点,可保证元素的唯一性
代码实现为:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set_node = new HashSet<>();
ListNode cur = head;
while(cur!=null){
if(!set_node.add(cur)){
return cur;
}
cur = cur.next;
}
return null;
}
}