链表-oj题

 1.返回倒数第k个节点

题解:定义两个快慢指针或着快慢变量。1.让fast先走k-1步   2.fast走完,在跟show一起走

3. 走到fast.next == null结束,返回show.val

 yH5BAAAAAAALAAAAAAOAA4AAAIMhI+py+0Po5y02qsKADs=

 public int kthToLast(ListNode head, int k) {
        if (k <=0 || head == null ) {
            return -1;
        }
        ListNode fast = head;
        ListNode show = head;
        //fast先走k-1步
        while (k-1 != 0) {
            fast = fast.next;
            if (fast == null) {
                return -1;
            }
            k--;
        }
        //fast、show一起走
        while (fast.next != null) {
            fast = fast.next;
            show = show.next;
        }
        return show.val;
    }

2.回文链表

题解:1.找到中间节点吗

  2.该链表为单向链表,所以需要把中间节点的后半部反转

  3.在处理一些其它情况(链表为偶数)

 

 

 public boolean isPalindrome(ListNode head) {
        if (head == null) {
            return true;
        }
        if (head.next == null) {
            return true;
        }
        ListNode slow = head;
        ListNode fast = head;
        //找中间节点
        while (fast != null && fast.next != null) {
              fast = fast.next.next;
              slow = slow.next;
        }
        ListNode car = slow.next;
        //反转
        while (car != null) {
            ListNode curNext = car.next;
            car.next = slow;
            slow = car;
            car = curNext;
        }
        while (head != slow) {
            if (head.val != slow.val) {
                return false;
            }
            //解决偶数链表
            if (head.next == slow) {
                return true;
            }
            if (head.val == slow.val){
                head = head.next;
                slow = slow.next;
            }
        }
     return true;
    }

 3.删除链表的倒数第n个节点

题解:1.先找到要删除的倒数第n个节点

          2.找删除节点的前一个节点   3.处理特殊情况

 public ListNode removeNthFromEnd ( int n) {
        if (n <= 0 || head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        ListNode car = head;
        int count = 1;
        while (n-1 != 0) {
            fast = fast.next;
            //处理n大于size()
            if (fast == null) {
                return null;
            }
            n--;
        }
        //找倒数第n个节点
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        //找删除节点的前一个节点
        if (car != slow) {
            while (car.next != slow) {
                if (car.next == null) {
                    return null;
                }
                car = car.next;
                count++;
            }
            car.next = slow.next;
        } else {
            if ( n == count) {
                head = head.next;
            }
        }
        return head;
    }

 4.链表分割

 

题解: 1.用car遍历链表分割成两部分,节点放在<x || >= x

            2.定义bs、be记录<x,as、ae记录 >= x,且bs和as永远都是两部分的头  、

           3.处理一些特殊情况         

 

 public ListNode partition(ListNode head, int x) {
        ListNode bs = null;
        ListNode be = null;
        ListNode as = null;
        ListNode ae = null;
        ListNode car = head;
        while (car != null) {
            if (car.val < x) {
                if (bs == null) {
                    bs = car;
                    be = car;
                } else {
                    be.next = car;
                    be = be.next;
                }
            } else {
                if (as == null) {
                    as = car;
                    ae = car;

                } else {
                    ae .next = car;
                    ae = ae.next;
                }
            }
            car = car.next;
        }
        //如果链表没有出现小于X或大于等于X
        if (bs == null) {
            return as;
        }
        //第一段不为空
        be.next = as;
        if (as != null) {
            ae.next = null;
        }
        return bs;
    }

5.相交链表

 

题解:1.两个链表相交,不同点就是相交点之前的长度可能不同

           2.求两个链表的长度

           3.让长链表先走这两个链表的差(大于0)

          

 

public MySingleList.ListNode getIntersectionNode(MySingleList.ListNode headA, MySingleList.ListNode headB) {
        MySingleList.ListNode bl = headA;
        MySingleList.ListNode as = headB;
        int lenA = 0; //记录链表长度
        int lenB = 0;
        //记录两链表的长度
         while (bl != null) {
             lenA++;
             bl = bl.next;
         }
         while (as != null) {
             lenB++;
             as = as.next;
         }
        int let = lenA - lenB;
         //while循环结束bl、as会为null,重新指向
         bl = headA;
         as = headB;
         //1.let一定为正数 2.bl一定是长链表
         if (let < 0) {
             bl = headB;
             as = headA;
             let = lenB - lenA;
         }
         //bl先走
         while (let > 0) {
             bl = bl.next;
             let--;
         }
         while (bl != as) {
             bl = bl.next;
             as = as.next;
         }
         return bl;
    }

 6.合并两个排序的链表

 

 题解:1.定义一个新的节点,用的记录合并之后的head地址

            2.定义一个temp起始放在新节点的位置,用来传递两个链表比较之后的指向

            3.对一些特殊情况进行处理

 

 

public ListNode Merge (ListNode head1, ListNode head2) {
        ListNode newHead = new ListNode(0);
        ListNode temp = newHead;
        while (head1 != null && head2 != null) {
            if (head1.val < head2.val) {
                temp.next = head1;
                head1 = head1.next;
            } else {
                temp.next = head2;
                head2 = head2.next;
            }
            temp = temp.next;
        }
        if (head1 != null && head2 == null) {
            temp.next = head1;
        }
        if (head2 != null && head1 == null) {
            temp.next = head2;
        }
        return newHead.next;
    }
方法不唯一!!!
  • 27
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值