白银挑战-链表高频面试算法题

两个链表的公共子结点

通过建立Hash表辅助查询
先遍历第一个链表head1以val为key,yiNode为value添加到map中
遍历第二个链表head2,遍历并判断map中有无head2,无的话直接下一个,有的话就返回节点

/**
     * 方法1:通过Hash辅助查找
     *
     * @param pHead1
     * @param pHead2
     * @return
     */
    public static ListNode findFirstCommonNodeByMap(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) {
            return null;
        }
        Map<Integer, ListNode> map = new HashMap<>();
        while (pHead1 != null) {
            map.put(pHead1.val, pHead1);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null) {
            if (!map.containsKey(pHead2.val)) {
                pHead2 = pHead2.next;
            } else {
                return map.get(pHead2.val);
            }
        }
        return null;
    }

通过HashSet来辅助查找

 /**
     * 方法2:通过集合来辅助查找
     *
     * @param headA
     * @param headB
     * @return
     */
    public static ListNode findFirstCommonNodeBySet(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        Set<ListNode> set = new HashSet<>();
        while (headA != null) {
            set.add(headA);
            headA = headA.next;
        }
        while (headB != null) {
            if (!set.contains(headB)) {
                headB = headB.next;
            } else {
                return headB;
            }
        }
        return null;
    }

链表是否为回文序列 LeetCode234

通过双指针进行判断
快慢指针可以找到链表的中间位置,快指针一次走两步,慢指针一次走一步。
但是这里需要注意慢指针到达中点后就无法访问到前边的节点了,所以需要在慢指针前进的过程中做链表反转,才可以做到后续再向前遍历。

 /**
     * 方法1:通过双指针的方式来判断
     *
     * @param head
     * @return
     */
    public static boolean isPalindromeByTwoPoints(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        ListNode slow = head;
        ListNode fast = head;
        ListNode pre = head;
        ListNode prePre = null;
        while (fast != null && fast.next != null) {
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
            pre.next = prePre;
            prePre = pre;
        }
        while (pre != null && slow != null) {
            if (pre.val != slow.val) {
                return false;
            }
            pre = pre.next;
            slow = slow.next;
        }
        return true;
    }

通过使用栈
一次遍历将链表的值全部压入栈中,然后遍历链表和栈中的值,出现不一致则表示不是回文。
可以优化为只判断一半的值

 /**
     * 方法1:通过双指针的方式来判断
     *
     * @param head
     * @return
     */
    public static boolean isPalindromeByTwoPoints(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        ListNode slow = head;
        ListNode fast = head;
        ListNode pre = head;
        ListNode prePre = null;
        while (fast != null && fast.next != null) {
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
            pre.next = prePre;
            prePre = pre;
        }
        while (pre != null && slow != null) {
            if (pre.val != slow.val) {
                return false;
            }
            pre = pre.next;
            slow = slow.next;
        }
        return true;
    }

合并有序链表

建立新链表 逐个比较两个链表节点的值,取小的插入新链表中。
一个为null之后,直接将剩下不为空的链表整个接上。

/**
     * 方法1:建立新链表 逐个比较两个链表节点的值,取小的插入新链表中
     *
     * @param list1
     * @param list2
     * @return
     */
    public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // write code here 建立新链表 逐个比较两个链表节点的值,取小的插入新链表中
        ListNode preHead = new ListNode(-1);
        ListNode node = preHead;
        while (list1 != null && list2 != null) {
            if (list1.val > list2.val) {
                node.next = list2;
                list2 = list2.next;
            } else {
                node.next = list1;
                list1 = list1.next;
            }
            node = node.next;
        }
        node.next = list1 == null ? list2 : list1;
        return preHead.next;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值