[Algorithm]九章六之一:LinkedList

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值