LinkedList主要注意的就是,快慢指针找中点,如果头节点要变的话得要在头节点前面加dummyNode。
83. Remove Duplicates from Sorted List 遇到相同的跳过,不相同的继续
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head == null){
return null ;
}
ListNode node = head ;
while(node.next != null){
if(node.val == node.next.val){
node.next = node.next.next ;
}else{
node = node.next ;
}
}
return head ;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head == null || head.next == null){
return head ;
}
ListNode dummy = new ListNode(0) ;
dummy.next = head ;
head = dummy ;
while( head.next != null && head.next.next != null ){
if(head.next.val == head.next.next.val){
int val = head.next.val;
// 注意要先判断是不是null要不然会空指针 & && 区别
while( head.next != null && head.next.val == val ){
head.next = head.next.next ;
}
}else{
head = head.next ;
}
}
return dummy.next ;
}
}
206
.
Reverse Linked List翻转链表主要用到了头插法,要仔细理解指针的变化
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
// 头插法,每次往头部插; *****头节点有可能变化的情况下都要在头节点前加新节点 ;
ListNode pre = new ListNode(0);
ListNode nextNode ;
if(head == null || head.next == null){
return head ;
}
while(head != null){
nextNode = head.next ;
head.next = pre.next ;
pre.next = head ;
head = nextNode ;
}
return pre.next ;
}
}
92
.
Reverse Linked List II上一题的升级版,要给制定区间的链表进行反转,思路就是找到制定区间第一个节点的前一个节点和指定区间最后一个节点的后一个节点,然后对区间翻转,然后再连接上
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (m >= n || head == null) {
return head;
}
ListNode cur = new ListNode(0);
cur.next = head;
head = cur;
// 先让head走到m的前一位;
for (int i = 1; i < m; i++) {
if (head == null) {
return null;
}
head = head.next;
}
// m的前一位
ListNode premNode = head;
// 第m个节点
ListNode mNode = head.next;
// 第n个节点(先从m点开始) n的后一位
ListNode nNode = mNode, postnNode = nNode.next;
// 从m走到n
for (int i = m; i < n; i++) {
if(postnNode == null) {
return null ;
}
// 这个注意是存头节点的下下一个节点 ;
ListNode temp = postnNode.next;
postnNode.next = nNode;
nNode = postnNode;
postnNode = temp;
}
mNode.next = postnNode;
premNode.next = nNode;
return cur.next;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
// 这道题就是说给定一个x的值,小于x都放在大于等于x的前面,并且不改变链表之间node原始的相对位置。每次看这道题我老是绕晕,纠结为什么4在3的前面。。其实还是得理解题意,4->3->5都是大于等3的数,而且这保持了他们原来的相对位置 。
// 所以,这道题是不需要任何排序操作的,题解方法很巧妙。
// new两个新链表,一个用来创建所有大于等于x的链表,一个用来创建所有小于x的链表。
// 遍历整个链表时,当当前node的val小于x时,接在小链表上,反之,接在大链表上。这样就保证了相对顺序没有改变,而仅仅对链表做了与x的比较判断。
// 最后,把小链表接在大链表上,别忘了把大链表的结尾赋成null。
// class Solution {
public ListNode partition(ListNode head, int x) {
if(head == null){
return null ;
}
ListNode leftDummy = new ListNode(0);
ListNode rightDummy = new ListNode(0);
ListNode left = leftDummy ;
ListNode right = rightDummy ;
while(head != null){
if(head.val < x){
left.next = head ;
left = head ;
}else{
right.next = head ;
right = head ;
}
head = head.next ;
}
left.next = rightDummy.next ;
right.next = null ;
return leftDummy.next ;
}
}
141. Linked List Cycle 判断链表是否有环,超级经典基础题,快慢指针相遇即是有环
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null){
return false ;
}
ListNode fast = head ;
ListNode slow = head ;
while(fast != null && fast.next != null){
slow = slow.next ;
fast = fast.next.next ;
if(fast == slow){
return true ;
}
}
return false ;
}
}
具体分析看这篇博客
/**
* 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) {
if(head == null || head.next == null){
return null ;
}
ListNode fast = head ;
ListNode slow = head ;
while(fast != null && fast.next != null){
slow = slow.next ;
fast = fast.next.next ;
if(fast == slow){
break ;
}
}
// 这一步就是为了避免 fast slow 都为null 也是可能相等的;
if(fast == null || fast.next == null){
return null ;
}
slow = head ;
while(fast != slow){
slow = slow.next ;
fast = fast.next ;
}
return slow ;
}
}
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null){
return null ;
}
HashMap map = new HashMap() ;
RandomListNode newHead = new RandomListNode(head.label) ;
RandomListNode pre = newHead ;
RandomListNode node = head.next ;
map.put(head ,newHead );
while(node != null){
RandomListNode newNode = new RandomListNode(node.label) ;
map.put(node , newNode) ;
pre.next = newNode ;
pre = newNode ;
node = node.next ;
}
// 让指针都回到链表开始的地方
node = head ;
RandomListNode copyNode = newHead ;
while(node != null){
copyNode.random = map.get(node.random) ;
copyNode = copyNode.next ;
node = node.next ;
}
return newHead ;
}
}