回文链表、链表求和(234、445)
第234题
请判断一个链表是否为回文链表。
示例
输入: 1->2 输出: false
输入: 1->2->2->1 输出: true
分析
回文链表就是链表中的元素是对称相等的,通过这个特点,可以借助于栈,如果链表的元素个数是奇数个,那么就将最中间元素左边的元素存入栈,然后再依次出栈与中间元素的右边元素进行逐个的比较。如果都相等,那么就是回文链表,否则不是。如果元素的个数是偶数个,那就直接将前半部分存入栈,然后与后半部分逐个的比较。
public boolean isPalindrome(ListNode head) { if (head == null || head.next == null){ return true; } Stack<Integer> stack = new Stack<>(); int length = 0; ListNode p = head; while (p != null){ length++; p = p.next; } p = head; for (int i = 1; i <= length / 2; i++) { stack.push(p.val); p = p.next; } if (length % 2 != 0){ p = p.next; } while (!stack.isEmpty()){ Integer n = stack.pop(); if (n != p.val){ return false; } p = p.next; } return true; }
第445题
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
分析:
一个链表代表一个非负的整数,数字的最高位在链表的开始位置,也就是说最低位在链表的结尾,因为链表是单链表所以想要没办法直接从链表尾部向前依次遍历到链表的开始位置,但是我们计算的时候,又必须得从低位开始计算,同时考虑进位的因素,所以这里也借助于栈,定义两个栈,分别存入两个链表的元素,存入之后,再依次弹出,由于栈是后进先出的原则,所以就能够实现从低位开始计算。实现的代码如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null && l2 == null){ return null; }else if (l1 == null){ return l2; }else if (l2 == null){ return l1; } ListNode head = new ListNode(-1); Stack<Integer> num1 = getStack(l1); Stack<Integer> num2 = getStack(l2); int carry = 0; while (!num1.isEmpty() ||!num2.isEmpty() || carry != 0){ int x = num1.isEmpty()?0:num1.pop(); int y = num2.isEmpty()?0:num2.pop(); int cur_sum = x + y + carry; int cur_num = cur_sum % 10; carry = cur_sum / 10; ListNode node = new ListNode(cur_num); node.next = head.next; head.next = node; } return head.next; } private Stack<Integer> getStack(ListNode l){ ListNode p = l; Stack<Integer> stack = new Stack<>(); while (p != null){ stack.push(p.val); p = p.next; } return stack; }