链表相加&回文链表

428 阅读2分钟

前言

“这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

总结下链表中相加 与 回文链表的判断问题

  1. NC40 两个链表生成相加链表(中等)
  2. NC96 判断一个链表是否为回文结构(简单)

相加链表

描述:假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。 给定两个这种链表,请生成代表两个整数相加值的结果链表。 例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。

思路分析:

  • 反转链表,生成一个虚拟的头节点 pre, 然后两个链表一起遍历,相加,将结果插入到 pre 的后面注意相加 进位(add) 以及遍历完之后 进位的值是否为 0
  • 借助栈, 将链表按顺序压入到 两个栈中, 然后一个个弹出 计算 生成新的节点 插入到 pre 的后面

tip: 数据量大时, 使用递归的方式反转链表可能会出现 StackOverFlowError 问题

AC 代码:

    public ListNode addInList(ListNode head1, ListNode head2) {
        // write code here
        head1 = reverseList(head1);
        head2 = reverseList(head2);

        int add = 0;
        int sum = 0;

        ListNode res = new ListNode(-1);
        ListNode head;

        while (head1 != null || head2 != null || add != 0) {
            int a = head1 == null ? 0 : head1.val;
            int b = head2 == null ? 0 : head2.val;
            sum = a + b + add;
            head= res.next;
            ListNode cur = new ListNode(sum % 10);
            res.next = cur;
            cur.next = head;

            add = sum / 10;
            head1 = head1 != null ? head1.next : null;
            head2 = head2 != null ? head2.next : null;

        }


        return res.next;
    }
    
public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) return head;

        ListNode pre = null;
        ListNode next;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

回文链表

描述:给定一个链表,请判断该链表是否为回文结构。

思路分析:

  • 使用栈 将链表压入栈中, 然后 从头遍历链表 和 从 栈中弹出节点, 判断值是否相等
  • 使用快慢指针, 找到中间节点, 将链表划分为 两部分,反转后一半, 遍历两部分链表比较, 最后再把链表反转回去

AC 代码:

    public boolean isPail (ListNode head) {
        // write code here
        if (head == null || 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 right = reverse(slow, null);
        ListNode rightBack = right;
        fast = head;
        
       while (right != null){
           if (right.val != fast.val){
               return false;
           }
           right = right.next;
           fast = fast.next;
       }
       
       reverse(rightBack, null);
       return true;
    }
    
    ListNode reverse(ListNode head, ListNode tail) {
        if (head == tail || head.next == tail) return head;

        ListNode pre = null;
        ListNode next;
        while (head != tail) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }