leetcode单链表总结

首先要链表的node类。

public class ListNode {
	     int val;
	     ListNode next;
	     ListNode(int x) { val = x; }
}

83: Remove Duplicates from Sorted List删除有序链表中重复元素

思路:由于链表是有序的,只需要定义一前一后两个对象q,p。如果两个对象所指向的元素相等,则去掉一个就可以了。

/**
	 * 删除有序链表重复元素
	 * @param head
	 * @return
	 */
	public ListNode deleteDuplicatesForSortedList(ListNode head) {   
        if(head==null||head.next==null)
            return head;
        ListNode q = head.next; //q在前
        ListNode preq = head;  //preq在后
        while(q != null){
            if(preq.val==q.val){  //相等则去掉q指向的元素
            	preq.next = q.next;
            	q = q.next;
            }else{
            	preq = q;
            	q = q.next;
            }    	
        }
        return head;
    }

此题的变种自然就是删除无序链表中的重复元素。

思路:由p从第一个元素开始遍历,当其指向第一个元素时,q以及指向其前一个元素的preq开始遍历整个链表找到相同的元素就删掉。

public ListNode deleteDuplicates(ListNode head) {
        ListNode p = head;
        ListNode q = head;
        ListNode preq = null;
        if(head==null)
            return head;
        while(p.next != null){  //遍历链表
            q = p.next;     //q从p的下一个元素开始
            preq = p;
            while(q!=null){    //直到q为null而不是q.next!=null
            	if(p.val==q.val){
            		preq.next = q.next;
                    q = q.next;
            	}else{
            		preq = q;
            		q = q.next;
            	}
            }
            if(p.next!=null)
                p = p.next;
        }
        return head;
    }


203: Remove Linked List Elements

删除链表中指定元素,用两个指针遍历,对比,删除。代码如下。

public ListNode removeElements(ListNode head, int val) {
	        if(head == null)
	            return head;
	        ListNode p = head;
	        ListNode prep = null;
	        while(p!=null){
	            if(p.val==val){
	                if(head==p){        //删除第一个节点的情况,此时prep为null,得单独处理
	                    head = p.next;
	                    if(head==null)
	                        return head;
	                }else{
	                    prep.next = p.next;
	                }
	            }else{
	                    prep = p;
	            }
	            p = p.next;
	        }
	        return head;
	    }

19:removeNthFromEnd删除从结尾数第n个元素。

两个指针p,q,p先走n步,然后一起走直到队尾。删掉q指向的元素就可以了。

public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode p=head;
        ListNode q=head;
        ListNode tmp=null;
        for(int i=1;i<n;++i){
                q = q.next;
        }
        while(q.next!=null){
            q = q.next;
            tmp = p;//tmp指向待删除节点前一个节点
            p = p.next; //p指向待删除节点
        }
        if(tmp==null){
            head = p.next;
        }else{
            tmp.next = p.next;
        }
        return head;
    }

206:逆置链表。

将链表的指针全部转向。好比p在前q在后,q=p.next;就可以了。

public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null)
            return head;
        ListNode p = head.next;
        head.next = null;
        ListNode q = head;
        ListNode tmp =null;
        while(p != null){
            tmp = p.next;
            p.next = q;
            q = p;
            p = tmp;
        }
        return q;
    }

21:合并两个有序链表。

对两个链表从头开始遍历,一个作为主链表,一个作为待插入链表。当待插入链表元素大于主链表时,插入。

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null&&l2==null)
        	return null;
        if(l1==null&&l2!=null)
        	return l2;
        if(l1!=null&&l2==null)
        	return l1;
		ListNode p = l1;
        ListNode q = l2;
        if(l1.val>l2.val){
        	p = l2;         //p指向第一个值较小的链表,主表
        	q = l1;         //q指向较大的,待插入链表
        }
        ListNode prep = null;
        while(p!=null){
        	if(q!=null&&q.val<p.val){
        		prep.next = q;
        		//遍历待插入链表,找到第一个小于p元素的,这中间的一段元素都需要插入到主表
	        	while(q!=null&&q.val<p.val){
	        		prep = prep.next;
	        		q = q.next;
	        	}
	        	prep.next = p;;
        	}
        	prep = p;
        	p = p.next;
        }
        prep.next = q;
        if(l1.val>l2.val){
        	return l2;
        }else{
        	return l1;
        }
    }


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值