从小问题看懂链表
从小问题看懂链表
前言
放暑假了,笔者趁这这段时间梳理一遍数据结构,今天我们先看一看基本的数据结构--链表。相对来说,我更喜欢从实际问题去理解
数据结构
这种抽象的概念。music,让我们开始吧!
第一问-回文字符串
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false示例 2:
输入: 1->2->2->1
输出: true进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
-
思路
由于要在 O(1) 的空间复杂度内解决次问题,所以我自然想到了双指针法。
步骤:
- 使用快慢两个指针,慢指针边走边逆序,当快指针到底时,字符串的前半部分完成逆序。
- 意义对比两部分即可
-
代码
/** * 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个节点,求中间节点等。熟练掌握这些你就学会链表这一结构,为以后的学习打下基础!