剑指offer-------链表、二叉树

剑指offer思路总结

 

1、链表

1.1 从尾到头打印链表

       题目概述:给出一个链表的表头,从尾到头反过来打印出每个结点的值。

(1)若可以改变链表

      思路:把链表反转,在遍历。

(2)不能改变链表

      思路:可以借助辅助栈的后进先出;

                 可以利用递归实现。

 

1.2 删除链表的结点

      题目一大致描述:给定一个单向链表的头结点和一个结点指针,要求在O(1)时间内删除该节点

      思路:因为要求是O(1),所以考虑先复制后结点的值,然后删除。需要注意头结点,尾结点情况。

   

      题目二大致描述:链表有序,删除链表中重复的结点

      思路:为了避免头结点可能被删除的情况,引进一个新的头结点,然后使用两个指针pre,cur进行即可。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null)
            return null;
        ListNode newHead = new ListNode(-1);
        newHead.next = head;
        ListNode cur = head;   //当前节点
        ListNode pre = newHead; //前驱节点
        while(cur != null && cur.next != null){
            if(cur.val == cur.next.val){  //判断是否相同
                int a = cur.val;
                while(cur != null && cur.val == a){  //找出不相同的节点
                    cur = cur.next;
                }
                pre.next = cur;    
                // pre = cur;  如果多了这条,会出错,所以需要注意
            }else{
                pre = cur;  
                cur = cur.next;
            }
        }   
        return newHead.next;
    }
}

      题目三:去重复元素,但每一个只保留一次。

      思路:一次遍历,出现相同就跳一个指针。

 

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode current = head;
        while(current != null && current.next != null){
            if(current.val == current.next.val){
                current.next = current.next.next;
            }else {
                current = current.next;
            }
        }
        return head;
    }
}

1.3 链表中的倒数第k个结点

      题目大致概述:给出一个链表,输出链表中倒数第k个结点。

      思路双指针,一个先走k步,然后同时起步。

 

1.4 链表中环的入口

     题目概述:一个链表中包含环,找出环的入口

     思路: 双指针,一个每次走一步,一个每次走两步,当相遇时,第二个指针刚好比第一个走多了一个环大小的距离,然后一个指针从头节点重新开始走,相遇时的节点就是环的入口。

 

1.5 反转链表

    题目概述:给定一个链表,反转该链表。

    思路:双指法。一个指针记录为反转的链表头节点,一个是反转了的链表的头节点。

class Solution {
    public ListNode reverseList(ListNode head) {
         if(head == null || head.next == null)
             return head;
         ListNode pre = null;
         ListNode cur = head;
         while(cur != null){
             ListNode next = cur.next;
             cur.next = pre;
             pre = cur;
             cur = next;
         }
         return pre;
    }
}

1.6 合并两个排序的链表

    题目概述:给定俩个递增的链表,合并两个链表,使其依旧是递增排序。

    思路:递归法。

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
         if(l1 == null)
             return l2;
         if(l2 == null)
             return l1;
         ListNode head = null;
         if(l1.val > l2.val){
             head = l2;
             head.next = mergeTwoLists(l1 , l2.next);
         }else {
             head = l1;
             head.next = mergeTwoLists(l1.next , l2);
         }    
         return head;
               
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值