从小问题看懂链表

从小问题看懂链表

前言

放暑假了,笔者趁这这段时间梳理一遍数据结构,今天我们先看一看基本的数据结构--链表。相对来说,我更喜欢从实际问题去理解 数据结构 这种抽象的概念。music,让我们开始吧!

第一问-回文字符串

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

  • 思路

    由于要在 O(1) 的空间复杂度内解决次问题,所以我自然想到了双指针法。

    步骤:

    1. 使用快慢两个指针,慢指针边走边逆序,当快指针到底时,字符串的前半部分完成逆序。
    2. 意义对比两部分即可
  • 代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public boolean isPalindrome(ListNode head) {
            if(head==null||head.next==null) return true;
            ListNode prev = null;
            ListNode slow = head;
            ListNode fast = head;
            ListNode next = null;
            while(fast!=null&&fast.next!=null){
                fast = fast.next.next;
                next = slow.next;
                slow.next = prev;
                prev = slow;
                slow = next;
            }
    
            if(fast!=null){
                slow = slow.next;
            }
            while(slow!=null){
                if(slow.val!=prev.val) return false;
                slow = slow.next;
                prev = prev.next;
            }
            return true;
        }
    }

第二问-环形链表

Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?

  • 思路:

    同样是快慢指针法,如果两指针能相遇则有环

  • 代码:

    public boolean hasCycle(ListNode head){
        if(!head) return false;
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next!=null && fast.next.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow)
                return true;
        }
        return false;
    }

总结

当然有关链表的题目有很多,大家可以自己去各大 OJ (leetcode等) 发掘,相类似的问题还有,单链表的反转,两个有序链表的合并,删除链表的倒数第n个节点,求中间节点等。熟练掌握这些你就学会链表这一结构,为以后的学习打下基础!

猜你喜欢

转载自www.cnblogs.com/jiaweixie/p/11305923.html