[Algorithm]九章六之一:LinkedList

来源:互联网 发布:纹身图案软件 编辑:程序博客网 时间:2024/06/05 10:26

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;    }}

/** * 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;    }}
原创粉丝点击