35.Reverse Linked List :点击打开链接
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The head of linked list.
* @return: The new head of reversed linked list.
*/
public ListNode reverse(ListNode head) {
ListNode prev=null;
while(head!=null){
ListNode temp=head.next;
head.next=prev;
prev=head;
head=temp;
}
return prev;
}
}
36. Reverse Linked List II: 点击打开链接
思路:由翻转链表的经验知道,如果原链表有3个Node,翻转2次,所以m~n中间段有n-m+1个Node翻转,要翻转n-m次
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param ListNode head is the head of the linked list
* @oaram m and n
* @return: The head of the reversed ListNode
*/
public ListNode reverseBetween(ListNode head, int m , int n) {
ListNode dummy=new ListNode(-1); //以1->2->3->4->5为例,部分反转城1->4->3->2->5
dummy.next=head;
head=dummy; //让链表头从dummy的位置开始
for(int i=1;i<m;i++){ //整个循环完知道head:m-1
head=head.next;
}
//这里的四个记录特别重要,因为最后还要表新链表连接到原来的链表上
ListNode preNode=head; //m-1:1
ListNode headSub=head.next; //m:2
ListNode nextNode=head.next.next;
ListNode curNode=head.next; //m:2
for(int i=m;i<n;i++){ //只动curNode和nextNode,翻转n-m次
ListNode temp=nextNode.next; //preNode和headSub不动
nextNode.next=curNode;
curNode=nextNode;
nextNode=temp;
}
preNode.next=curNode; //最后还要原来的1连接到新表表头4
headSub.next=nextNode; //原来的表头2,现在在sublist的最后,要和5相连
return dummy.next;
}
}
96. Partiiton List:点击打开链接
题意:是给定一个x的值,小于x都放在大于等于x的前面,并且不改变原链表node之间的相对位置。
new两个新链表,一个用来创建所有小于x的链表,一个用来创建所有大于等于x的链表,双dummy node
遍历整个链表时,如果当前node的val小于x,接在小链表上,反之,接在大链表上。
最后,小链表和大链表相接,别忘了把大链表的结尾指向null。
注意:这样就保证了原链表node间的相对顺序没有改变,而仅仅做了链表node与x的大小判断。所以,这道题是不需要任何排序操作的。
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The first node of linked list.
* @param x: an integer
* @return: a ListNode
*/
public ListNode partition(ListNode head, int x) {
ListNode dummySmall=new ListNode(-1);
ListNode small=dummySmall;
ListNode dummyBig=new ListNode(-1);
ListNode big=dummyBig;
if(head==null){
return head;
}
while(head!=null){
if(head.val<x){ //符合条件的往小链表上接
small.next=head;
small=small.next;
}else{ //符合条件的往大链表上接
big.next=head;
big=big.next;
}
head=head.next; //原链表一个一个滑动以进入while循环判断
}
small.next=dummyBig.next; //小链表的尾接大链表的头,dummyBig.next正是大链表的头
big.next=null;
return dummySmall.next; //dummySmall.next正是小链表的头,也是整个Partition后的链表的头
}
}
165.Merge Two Sorted List:点击打开链接
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) { //recursion
if(l1==null){
return l2;
}
if(l2==null){
return l1;
}
ListNode mergeHead;
if(l1.val<l2.val){
mergeHead=l1;
mergeHead.next=mergeTwoLists(l1.next, l2);
}else{
mergeHead=l2;
mergeHead.next=mergeTwoLists(l1,l2.next);
}
return mergeHead;
}
}
2. Add Two Numbers
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode head = dummy;
int carry = 0;
while(l1 != null || l2!= null)
{
int val1 = l1 != null ? l1.val : 0;
int val2 = l2 != null ? l2.val : 0;
int curSum = val1 + val2 + carry;
int curDigit = curSum % 10;
carry = curSum / 10;
head.next = new ListNode(curDigit);
l1 = l1 != null ? l1.next : null; // 要判断当前的是否为空,即使为空,赋值到后一位也没关系,因为下一轮的l1或者l2新值还会判断是否为空之后,才取值
l2 = l2 != null ? l2.next : null;
head = head.next;
}
if(carry != 0) // [5], [6], 会有一位carry剩余,要加进去
{
head.next = new ListNode(carry);
}
return dummy.next;
}
}
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param ListNode l1 is the head of the linked list
* @param ListNode l2 is the head of the linked list
* @return: ListNode head of linked list
*/
public ListNode mergeTwoLists(ListNode l1, ListNode l2) { //non-recursion
ListNode dummy=new ListNode(-1);
ListNode newHead=dummy;
if(l1==null){
return l2;
}
if(l2==null){
return l1;
}
while(l1!=null && l2!=null){
if(l1.val<l2.val){
newHead.next=l1;
l1=l1.next;
}else{
newHead.next=l2;
l2=l2.next;
}
newHead=newHead.next;
}
if(l1!=null){ //最后把没有遍历完的剩余链表接在链表后
newHead.next=l1;
}
if(l2!=null){
newHead.next=l2;
}
return dummy.next;
}
}
112.Remove Duplicates from Sorted List:点击打开链接
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param ListNode head is the head of the linked list
* @return: ListNode head of linked list
*/
public static ListNode deleteDuplicates(ListNode head) {
ListNode dummy=new ListNode(-1);
dummy.next=head;
if(head==null){
return head;
}
while(head.next!=null){
if(head.val==head.next.val){
head.next=head.next.next;
}else{
head=head.next;
}
}
return dummy.next;
}
}
113.Remove Duplicates from Sorted List II :点击打开链接
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param ListNode head is the head of the linked list
* @return: ListNode head of the linked list
*/
public static ListNode deleteDuplicates(ListNode head) {
ListNode dummy=new ListNode(-1);
dummy.next=head;
head=dummy; //开始头在dummy位置,方便处理从头开始就重复的情况
//例如1->1->1->2->2->3->4
if(head==null){
return head;
}
while(head.next!=null && head.next.next!=null){
if(head.next.val==head.next.next.val){
int duplicateVal=head.next.val; //记录重复值,用于后面的比较
while(head.next!=null && head.next.val==duplicateVal){ //重复段中每一个重复值都记录为duplicateVal
head.next=head.next.next; //使head.next指向重复值的下一位
}
}else{
head=head.next;
}
}
return dummy.next;
}
}
511.Swap Two Nodes in Linked List :点击打开链接
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
/**
* @param head a ListNode
* @oaram v1 an integer
* @param v2 an integer
* @return a new head of singly-linked list
*/
public ListNode swapNodes(ListNode head, int v1, int v2) {
ListNode pre=new ListNode(-1);
pre.next=head;
ListNode result=pre;
if(head==null || head.next==null){
return head;
}
ListNode pre1=pre;
ListNode pre2=pre;
ListNode node1=head;
ListNode node2=head;
int found=0;
while(head!=null){
if(head.val==v1){ //找到v1值相对应的node,使它前一个记为pre1,本身记为node1
pre1=pre;
node1=head;
found++;
}
if(head.val==v2){ //找到v2值相对应的node,使它前一个记为pre2,本身记为node2
pre2=pre;
node2=head;
found++;
}
pre=head;
head=head.next;
}
if(found!=2){ //如果V1,v2两个都不在给定链表里,就返回原链表
return result.next;
}
if(pre2==node1){ //情况1:pre1->node1->node2,而node2的前一个是pre2,因此pre2=node1
pre1.next=node2;
node1.next=node2.next;
node2.next=node1;
}else if(pre1==node2){ //情况2:pre2->node2->node1,而node1的前一个是pre1,因此pre1=node2
pre2.next=node1;
node2.next=node1.next;
node1.next=node2;
}else{ //情况3:例如3->5->node1->4->node2->6
pre1.next=node2;
pre2.next=node1;
ListNode temp=node1.next;
node1.next=node2.next;
node2.next=temp;
}
return result.next;
}
}
105.Copy List with Random Pointer:点击打开链接
/**
* 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 {
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
public RandomListNode copyRandomList(RandomListNode head) {
RandomListNode dummy = new RandomListNode(-1);
RandomListNode curNode = dummy;
Map<RandomListNode, RandomListNode> map = new HashMap<>();
while (head != null) {
RandomListNode newNode = null;
if (map.containsKey(head)) {
newNode = map.get(head);
} else {
newNode = new RandomListNode(head.label);
map.put(head, newNode);
}
curNode.next = newNode;
if (head.random != null) {
if (map.containsKey(head.random)) {
newNode.random = map.get(head.random);
} else {
newNode.random = new RandomListNode(head.random.label);
map.put(head.random, newNode.random);
}
}
head = head.next; //原链表往下循环
curNode = curNode.next; //deepCopy的链表的往下拼接
}
return dummy.next;
}
}
102.Linked List Cycle:点击打开链接
注意:fast.next!=null 一定要写,因为要判断fast.next.next!=null,
如果fast.next==null,对于fast.next.next来说是null.next所以会出现空指针异常
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The first node of linked list.
* @return: True if it has a cycle, or false
*/
public boolean hasCycle(ListNode head) { //两指针法:一个快指针,一个慢指针
if(head==null){ //如果两者会重合,一定hasCycle
return false; //因为如果没有Cycle的话,fast的会先到达null,就会return false了
}
ListNode slow=head;
ListNode fast=head;
while(fast.next!=null && fast.next.next!=null){//如果没有fast.next会出现空指针异常
slow=slow.next;
fast=fast.next.next;
if(slow==fast){ //结果是slow追上fast
return true;
}
}
return false;
}
}
103. Linked List Cycle II :点击打开链接
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The first node of linked list.
* @return: The node where the cycle begins.
* if there is no cycle, return null
*/
public ListNode detectCycle(ListNode head) {
ListNode slow=head;
ListNode fast=head;
ListNode meet=head;
if(head==null){
return head;
}
while(fast.next!=null && fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast){ //到快慢指针相遇的时候,一个从头开始走,一个还是从相遇的地方走
while(slow!=meet){ //一步一走,到再相遇的时候的值,就是Cycle的起始位置
slow=slow.next;
meet=meet.next;
}
return meet;
}
}
return null;
}
}
599.Insert into a Cyclic Sorted List:点击打开链接
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution { //这题的想法是插入x是有一个时机的,还要注意node的值可能有重复
/**
* @param node a list node in the list
* @param x an integer
* @return the inserted new list node
*/
public ListNode insert(ListNode node, int x) {
if (node == null) { //如果node是null,就要造一个新node,并且自己和自己连上
node = new ListNode(x);
node.next = node;
return node;
}
ListNode head = node;
while (node != null && node.next != null) {
if (node.val < node.next.val) { //如果node.val<node.next.val
if (node.val <=x && x <=node.next.val) { //如果x在这中间,插入x
insertNode(node, x);
break;
}
}else if (node.val > node.next.val) { //如果node.val>node.next.val
if (x > node.val || x < node.next.val) { //说明node是最后一个节点,并且是当前最大节点,而node.next是最小节点
insertNode(node, x); //如果x大于当前最大节点,或者小于当前最小节点,直接插入x
break;
}
}else { //如果node.val=node.next.val
if (node.next == head) { //如果node是最后一个节点,也就是说node.next是头,插入x
insertNode(node, x);
break;
}
}
node = node.next;
}
return head;
}
public void insertNode(ListNode node, int x) {
ListNode newNode = new ListNode(x);
newNode.next = node.next;
node.next = newNode;
}
}
98.Sort List:点击打开链接
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The head of linked list.
* @return: You should return the head of the sorted linked list,
using constant space complexity.
*/
public ListNode sortList(ListNode head) {
if (head == null || head.next==null) {
return head;
}
ListNode mid = findMiddle(head);
ListNode right = sortList(mid.next);
mid.next = null; //从中间之后断开成两个分链表,然后按着大小merge
ListNode left = sortList(head); //必须先写右边,如果先写左边就不知道左边在哪里结尾
return merge(left, right); //也是分治思想,左边和右边的分链表先排序,然后再进行一次大排序
} //例如:左边排好:1->3, 右边排好:2->4, 大排序:1->2->3->4
private ListNode findMiddle(ListNode head) {
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
private ListNode merge(ListNode head1,ListNode head2){
ListNode dummy=new ListNode(-1);
ListNode tail=dummy;
while(head1!=null && head2!=null){
if(head1.val<head2.val){
tail.next=head1;
head1=head1.next;
}else{
tail.next=head2;
head2=head2.next;
}
tail=tail.next;
}
if(head1!=null){
tail.next=head1;
}
if(head2!=null){
tail.next=head2;
}
return dummy.next;
}
}
372. Delete Node in the Middle of Singly Liked List:点击打开链接
首先:看这题的中文版题意:给定一个单链表中的一个等待被删除的节点(非表头或表尾)。请在在O(1)时间复杂度删除该链表节点。
然后:说一下这题与通常不同的是:没有给出链表的起点,只给了一个等待被删除的节点,以前遇到的情况是:要删除一个节点的方法是要有其前一个节点的位置,然后将其前一个节点的next连向要删节点的下一个,然后delete掉要删的节点即可。
思路:先把当前节点的值用下一个节点的值覆盖了,然后删除下一个节点即可。
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param node: the node in the list should be deleted
* @return: nothing
*/
public void deleteNode(ListNode node) {
if(node==null || node.next == null){
return;
}
ListNode next=node.next;
node.val=next.val;
node.next=next.next;
}
}