恋上数据结构与算法第三季02

1._203移除链表元素

标签:链表

思路:1.当作构建一个新的链表,设置一个newHead指向新链表的头,cur指向新链表的尾节点。

           2.遍历整个链表,遇到与要删除的值相同的节点,跳过,不相同的加入到新链表中。

           3.最后cur.next应该指向空

注意点:虚拟头节点的使用

代码:

 public ListNode removeElements(ListNode head, int val) {
        if(head == null) return null;
        ListNode newHead = new ListNode(0);
        ListNode cur = newHead;
        while(head != null){
            if(head.val != val){
                cur.next = head;
                cur = head;
            }
            head = head.next;
        }
        cur.next = null;
        return newHead.next;
    }

2.2_两数相加

标签:链表

思路:1.设置一个新的链表来表示它们的和,利用虚拟头节点,设置newHead指向新链表头部,               newTail指向尾部。

           2.依次遍历两个链表,将遍历的节点的值和category进位相加,new一个新的节点来存储和             的个位数(i %10),设置category为进位标志。若(i/10)>1 ,则进位

           3.结束条件:两个链表都为空。最后要判断一下进位标志。

  public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1 == null) return l2;
        if(l2 == null) return l1;
        int category = 0;//进位标志
        ListNode newHead = new ListNode(0);
        ListNode newTail = newHead;
        while(l1 != null || l2 != null){ //如果l1或l2为空,该怎么处理?
            int v1 = 0;
            if(l1 != null){
                v1 = l1.val;
                l1 = l1.next;
            }
            int v2 = 0;
            if(l2 != null){
                v2 = l2.val;
                l2= l2.next;
            }
            int result = v1 + v2 + category ;
            newTail = newTail.next = new ListNode(result % 10);
            category = result / 10;
        }
        if(category == 1){
            newTail.next = new ListNode(1);
        }
        return newHead.next;
    }

 3._160相交链表

标签:链表 双指针

思路:1.将两个链表相加,使得两个链表的长度一致。

           2.从头至尾遍历两个链表,比较两个链表的元素是否相等。

代码:

   public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) return null;
        ListNode curA = headA;
        ListNode curB = headB;
        while(curA != curB ){

            curA =  (curA == null) ? headB : curA.next;
            curB =  (curB == null) ? headA : curB.next;
        }
        return curA;


    }

4._86分隔链表 

标签:链表

思路:1.可以想象成将链表分割成两个链表,比特定值小的在左链表,比特定值大的在右链表,最               后将两个链表连接在一起。

           2.设置两个虚拟头节点,一个指向左链表,一个指向右链表,然后对左右链表进行添加。

注意点:右链表的尾节点要清空,这一句非常重要 //因为可能出现这样的情况:原链表倒数第N个节点A的值是>=x的,A后面所有节点的值都是<x的 //然后rTail.next最终其实就是A.next

代码:

 public ListNode partition(ListNode head, int x) {
        ListNode lHead = new ListNode(0);
        ListNode lTail = lHead;
        ListNode rHead = new ListNode(0);
        ListNode rTail = rHead;
        while(head != null){
            if(head.val < x){//左链表
                lTail.next = head;
                lTail = head;
            }else{
                rTail.next = head;
                rTail = head;
            }
            head = head.next;
        }
        rTail.next = null;
        lTail.next = rHead.next;
        return lHead.next;
    }

 5._234回文链表

标签:链表、双指针、反转链表、找链表中间元素

思路:找到中间节点,然后对中间结点右侧的节点进行翻转。最后遍历比较左右链表元素是否相               同。

代码:

 public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null) return true;
        if(head.next.next == null) return head.val == head.next.val;
        ListNode middleNode = FindMiddleNode(head);//找到中间结点
        ListNode rHead = reverseList(middleNode.next);//翻转右边链表
        while(rHead != null){
            if(rHead.val != head.val) return false;
            rHead = rHead.next;
            head = head.next;
        }
        return true;


    }
    private ListNode FindMiddleNode(ListNode head){
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;

    }
    private ListNode reverseList(ListNode head){
        ListNode newHead = null;
        while(head != null){
            ListNode tmp = head.next;
            head.next = newHead;
            newHead = head;
            head = tmp;
        }
        return newHead;
    }

6._24反转链表

 非递归方法:头插法,每次往头部插入一个节点

思路:设置一个newHead先指向空,然后将head.next指向newHead,newHead指向head.head需要继续往下遍历。但是head.next已经指向newHead了,找不到原来链表head.next指向的内容。所以从一开始就要新建一个指针tmp指向head.next.这样head = tmp,tmp = head.next,便可将整个链表遍历完成。

代码:

    public ListNode reverseList(ListNode head) {
        ListNode newHead = null;
        while(head != null){
            ListNode tmp = head.next;
            head.next = newHead;
            newHead = head;
            head = tmp;
        }
        return newHead;
        
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值