算法练习LeetCode初级算法之链表
- 
删除链表中的节点

| /** | 
| * Definition for singly-linked list. | 
| * public class ListNode { | 
| * int val; | 
| * ListNode next; | 
| * ListNode(int x) { val = x; } | 
| * } | 
| */ | 
| class Solution { | 
| public void deleteNode(ListNode node) { | 
| node.val=node.next.val; | 
| node.next=node.next.next; | 
| } | 
| } | 
- 
删除链表的倒数第N个节点
- 
两次遍历算法class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy=new ListNode(0); dummy.next=head; int length=0; ListNode p=head; while (p!=null) { length++; p=p.next; } ListNode first=dummy; length-=n; while (length>0) { length--; first=first.next; } first.next=first.next.next; return dummy.next; } } 
- 
一次遍历算法class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode first = dummy; ListNode second = dummy; // Advances first pointer so that the gap between first and second is n nodes apart for (int i = 1; i <= n + 1; i++) { first = first.next; } // Move first to the end, maintaining the gap while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; return dummy.next; } } 
- 
反转链表
- 
我的解法:利用Linklist比较好理解,有点投机取巧,面试不一定可以得吧!!!哈哈哈,但是测试通过了class Solution { public ListNode reverseList(ListNode head) { LinkedList<Integer> list=new LinkedList<>(); for(ListNode x=head;x!=null;x=x.next) { list.add(x.val); } for(ListNode x=head;x!=null;x=x.next) { x.val=list.removeLast(); } return head; } } 
- 
迭代法,一开始不好理解,仔细琢磨后还是很好理解的class Solution { public ListNode reverseList(ListNode head) { if (head==null||head.next==null) { return head; } ListNode newHead=null; while (head!=null) { ListNode temp=head.next;//先把后面的数据储存到temp head.next=newHead;//把head添加到newHead newHead=head;//把head添加到newHead,newHead重新作为新的头指针 head=temp;//让头指针指向下一个数据,已保存在temp里 } return newHead; } } 
- 
递归法,仔细研究后还是可以理解的class Solution { public ListNode reverseList(ListNode head) { return newHead(head); } public ListNode newHead(ListNode head) { if (head==null||head.next==null) { return head; } ListNode newHead=newHead(head.next); head.next.next=head;//反转链表,把把下一个数连接到newHead上 head.next=null;//指向空,防止再次递归导致覆盖后面的内容。 return newHead; } } 
以上两种方法,通过从网站学习理解,必须站在巨人的肩膀上,哈哈哈!
注明学习网址:https://blog.csdn.net/fx677588/article/details/72357389,虽然不是转载,但有借鉴。
- 
合并两个有序链表
- 
我的解法:很好实现,思路简单,但耗时长一点class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { LinkedList<Integer> list=new LinkedList<>(); for(ListNode x=l1;x!=null;x=x.next) { list.add(x.val); } for(ListNode x=l2;x!=null;x=x.next) { list.add(x.val); } Collections.sort(list); ListNode head=null; for (int i = list.size()-1; i>=0; i--) { ListNode n=new ListNode(list.get(i)); n.next=head; head=n; } return head; } } 
- 
大神一解法,递归解法,代码简洁class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode rspHead=new ListNode(0); ListNode rsp=rspHead; while(l1!=null && l2!=null){ if(l1.val<l2.val){ rspHead.next=l1; rspHead=rspHead.next; l1=l1.next; }else{ rspHead.next=l2; rspHead=rspHead.next; l2=l2.next; } } if(l1==null){ rspHead.next=l2; }else{ rspHead.next=l1; } return rsp.next; } } 
- 
大神二解法,利用双指针,现将带头链表头指针用rsp保存,最后返回rsp.nextclass Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode rspHead=new ListNode(0); ListNode rsp=rspHead; while(l1!=null && l2!=null){ if(l1.val<l2.val){ rspHead.next=l1; rspHead=rspHead.next; l1=l1.next; }else{ rspHead.next=l2; rspHead=rspHead.next; l2=l2.next; } } if(l1==null){ rspHead.next=l2; }else{ rspHead.next=l1; } return rsp.next; } } 
- 
回文链表
- 
我的解法:感觉已经脱离了链表,不行,不好,时间太长!class Solution { public boolean isPalindrome(ListNode head) { if (head==null||head.next==null) { return true; } LinkedList<Integer> list=new LinkedList<>(); for(ListNode x=head;x!=null;x=x.next) { list.add(x.val); } for (int i = 0; i < list.size()/2; i++) { if (list.get(i).compareTo(list.get(list.size()-i-1))!=0){ return false; } } return true; } } 
- 
大神解法:挺好!先找链表中点,然后再反转后半部分,最后再分别遍历比较,直到后半部分遍历完!class Solution { ListNode node1=new ListNode(0); ListNode node2=new ListNode(0); public boolean isPalindrome(ListNode head) { if (head==null||head.next==null) { return true; } ListNode slow=head; ListNode fast=head; while (fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; } slow=reverse(slow.next);//此处如果是show的话,将从中点的前一个匹配,比较难理解,后面附图说明 while (slow!=null) { if (head.val!=slow.val) {//到这里,head短的话会成为空指针而报错!!! return false; } head=head.next; slow=slow.next; } return true; } private ListNode reverse(ListNode head) { if (head==null||head.next==null) { return head; } ListNode newHead=reverse(head.next); head.next.next=head; head.next=null; return newHead; } } 
说明:如果测试样例输入0,0的话,黄色标记为什么会报错!

- 
环形链表
- 
我的解法:利用hashsetclass Solution { public boolean hasCycle(ListNode head) { if (head==null||head.next==null) { return false; } Set<ListNode> set=new HashSet<>(); int n=0; ListNode x=head; while (set.size()>=n) { set.add(x); x=x.next; n++; if (x==null) { return false; } } return true; } } 
- 
大神解法:class Solution { public boolean hasCycle(ListNode head) { if (head==null) { return false; } ListNode l1=head,l2=head.next; while (l1!=null&&l2!=null&&l2.next!=null) { l1=l1.next; l2=l2.next.next; if (l1==l2) { return true; } } return false; } } 
- 
递归解法,更为简洁class Solution { public boolean hasCycle(ListNode head) { if(head==null||head.next==null)return false; if(head.next==head)return true; ListNode l=head.next; head.next=head; boolean isCycle=hasCycle(l); return isCycle; } } 
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号