题目

设计一种方式检查一个链表是否为回文链表。

样例

1->2->1 就是一个回文链表。

挑战

O(n)的时间和O(1)的额外空间。

解题

法一:

再定义一个链表,存放链表反转的值,再以此比较两个链表中的值是否相等,时间复杂度O(N),空间复杂度O(N)

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
/**
* @param head a ListNode
* @return a boolean
*/
public boolean isPalindrome(ListNode head) {
// Write your code here
ArrayList<Integer> list = new ArrayList<Integer>();
if(head == null || head.next == null)
return true;
ListNode p = head;
ListNode prev = new ListNode(head.val);
while(p.next != null){
ListNode tmp = new ListNode(p.next.val);
tmp.next = prev;
prev = tmp;
p = p.next;
}
ListNode p1 = head;
ListNode p2 = prev;
while(p1!=null){
if(p1.val != p2.val)
return false;
p1 = p1.next;
p2 = p2.next;
}
return true; }
}

Java Code

总耗时: 2219 ms

Python下面程序出现内存溢出

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# @param head, a ListNode
# @return a boolean
def isPalindrome(self, head):
# Write your code here
if head == None or head.next == None:
return True
p = head
prev = ListNode(head.val)
while p.next!=None:
tmp = ListNode(p.next.val)
tmp.next = prev
prev = tmp
p = p.next
p1 = head
p2 = prev
del head
del prev
while p1!=None:
if p1.val != p2.val:
return False
p1 = p1.next
p2 = p2.next
return True

Python Code

法二:

先找到链表的中间节点,根据中间节点划分成两个链表,对第二个链表反转后在和第一个链表元素以此比较,但是下面的程序,在旋转的过程中空间复杂度好像是O(N/2) = O(N)

在找中间节点时候需要说明下

        ListNode slow = head;
ListNode fast = head;
// 找到两个链表的中间节点
while( fast.next!=null && fast.next.next!=null){
fast = fast.next.next;
slow = slow.next;
}

开始时候两个节点都指向第一个节点,以后两个异步的向前走

最后结束的时候

当长度是奇数的时候:slow恰好在中间节点,fast恰好在最后一个节点。slow.next就是下一个链表的头节点。你会发现这两个链表是不一样的长的,但是在比较的时候,只要有一个链表是null的时候就结束比较的,也就是说只与第二个链表有关系的。

当长度是偶数的时候:slow在N/2的下取整处的节点,也就是中间两个节点的前一个,二fast在倒数第二个节点,下面就一样了

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
/**
* @param head a ListNode
* @return a boolean
*/
public boolean isPalindrome(ListNode head) {
// Write your code here
if(head == null || head.next == null)
return true;
ListNode slow = head;
ListNode fast = head;
// 找到两个链表的中间节点
while( fast.next!=null && fast.next.next!=null){
fast = fast.next.next;
slow = slow.next;
}
ListNode secondHead = slow.next;
slow.next = null;
// 后半部分的节点反转
ListNode p1 = secondHead;
ListNode revsecondList = new ListNode(p1.val);
revsecondList.next = null;
while(p1.next != null){
ListNode tmp = new ListNode(p1.next.val);
tmp.next = revsecondList;
revsecondList = tmp;
p1 = p1.next;
} // 比较两个链表
while(head!=null && revsecondList!=null){
if(head.val != revsecondList.val)
return false;
head = head.next;
revsecondList = revsecondList.next;
}
return true;
}
}

Java Code

总耗时: 2229 ms

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# @param head, a ListNode
# @return a boolean
def isPalindrome(self, head):
# Write your code here
if head == None or head.next == None:
return True
slow = head
fast = head
while fast.next != None and fast.next.next != None:
fast = fast.next.next
slow = slow.next
secondHead = slow.next
slow.next = None
p = secondHead
rev = ListNode(p.val) while p.next!=None:
tmp = ListNode(p.next.val)
tmp.next = rev
rev = tmp
p = p.next while rev!=None and head!=None:
if rev.val != head.val:
return False
rev = rev.next
head = head.next
return True

Python Code

总耗时: 528 ms

在旋转链表的时候有重新定义了节点,如何只是修改节点而实现翻转,下面利用递归的思想翻转链表,但是在测试到97%的数据的时候运行时间超时。

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

Java Code

下面是定义两个指针,第一个指向头节点,第二个指向头节点后一个节点

p1 = head
p2 = p1.next
while(p1!= null && p2!= null){
ListNode tmp = p2.next;
p2.next = p1;
p1 = p2;
p2 = tmp;
}

操作如下图所示

这里可以最后A还指向B的,可以在初始定义中增加

p1 .next = null

这样每次都是在p1节点之前增加一个节点的

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
/**
* @param head a ListNode
* @return a boolean
*/
public boolean isPalindrome(ListNode head) {
// Write your code here
if(head == null || head.next == null)
return true;
ListNode slow = head;
ListNode fast = head;
// 找到两个链表的中间节点
while( fast.next!=null && fast.next.next!=null){
fast = fast.next.next;
slow = slow.next;
}
ListNode secondHead = slow.next;
slow.next = null;
// 后半部分的节点反转
ListNode p1 = secondHead;
ListNode p2 = p1.next;
p1.next = null; while(p1!= null && p2!= null){
ListNode tmp = p2.next;
p2.next = p1;
p1 = p2;
p2 = tmp;
}
secondHead.next = null;
revsecondList = p1;
// 比较两个链表
while(head!=null && revsecondList!=null){
if(head.val != revsecondList.val)
return false;
head = head.next;
revsecondList = revsecondList.next;
}
return true;
}
}

Java Code

总耗时: 2192 ms

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
# @param head, a ListNode
# @return a boolean
def isPalindrome(self, head):
# Write your code here
if head == None or head.next == None:
return True
fast = head
slow = head
while fast.next!= None and fast.next.next!=None:
fast =fast.next.next
slow = slow.next
secondhead = slow.next
slow.next = None p1 = secondhead
p2 = p1.next
p1.next = None
while p1!=None and p2!=None:
tmp = p2.next
p2.next = p1
p1 = p2
p2 = tmp
rev = p1
while rev!=None and head!=None:
if rev.val!=head.val:
return False
rev = rev.next
head = head.next
return True

Python Code

总耗时: 516 ms

lintcode 中等题:Palindrome Linked List 回文链表的更多相关文章

  1. [CareerCup] 2.7 Palindrome Linked List 回文链表

    2.7 Implement a function to check if a linked list is a palindrome. LeetCode上的原题,参见我之前的博客Palindrome ...

  2. [LeetCode] Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  3. [LeetCode] 234. Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ...

  4. 234 Palindrome Linked List 回文链表

    请检查一个链表是否为回文链表. 进阶:你能在 O(n) 的时间和 O(1) 的额外空间中做到吗? 详见:https://leetcode.com/problems/palindrome-linked- ...

  5. [Swift]LeetCode234. 回文链表 | Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ...

  6. LeetCode 234:回文链表 Palindrome Linked List

    ​ 请判断一个链表是否为回文链表. Given a singly linked list, determine if it is a palindrome. 示例 1: 输入: 1->2 输出: ...

  7. LeetCode OJ:Palindrome Linked List(回文链表判断)

    Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...

  8. 如何判断一个单向链表是否为回文链表(Palindrome Linked List)

    题目:给定一个单向链表,判断它是不是回文链表(即从前往后读和从后往前读是一样的).原题见下图,还要求了O(n)的时间复杂度O(1)的空间复杂度. 我的思考: 1,一看到这个题目,大脑马上想到的解决方案 ...

  9. 回文链表 · Palindrome Linked List

    [抄题]: 设计一种方式检查一个链表是否为回文链表.1->2->1 就是一个回文链表. [暴力解法]: 时间分析: 空间分析: [思维问题]: 以为要从从后往前扫描,不知道调用revers ...

随机推荐

  1. NSS_09 gridpanel中的actioncolumn事件

    在设计角色权限时, 终于用到了grid的actioncolumn,如下: { header: '权限设定', xtype: 'actioncolumn', items: [{ icon: 'Conte ...

  2. Linux下iftop网卡流量监控使用

    在类linux系统中可以使用top查看系统资源.进程.内存占用等信息.查看网络状态可以使用netstat.nmap等工具.若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop. 一.i ...

  3. iTerm2 颜色配置

    1. 首先找到配色文件: iterm2官网配色方案iTerm2-Color-Schemes altercation的  solarized配色方案solarized 2. 配置步骤: clone上面的 ...

  4. php生成圆形图片

    http://files.cnblogs.com/files/adtuu/circle_image.zip

  5. 51nod1269 B君的圆锥

    1629 B君的圆锥 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 B君要用一个表面积为S的圆锥将白山云包起来.   B君希望包住的白山云体积尽量 ...

  6. jquery鼠标滑过提示title具体实现代码

    jquery鼠标滑过提示title的实现代码. 如下: <script type="text/javascript" src="http://ajax.google ...

  7. python: 实现sha1小工具

    File1: sha1.py File2: sha1.bat ------------------ File1: sha1.py import hashlib import os,sys def Ca ...

  8. openerp模块收藏 移除下拉选择列表中的“创建并编辑”链接(转载)

    移除下拉选择列表中的“创建并编辑”链接 原文:http://shine-it.net/index.php/topic,5990.0.html 有时希望下拉列表中列出的项是与主表某个字段关联的,用户只能 ...

  9. Object.keys()

    Object.keys(obj),返回一个数组,数组里是该obj可被枚举的所有属性名.请看示例: 示例一: function Pasta(grain, width, shape) { this.gra ...

  10. 实用项目管理前台框架:EasyUI,ExtJs

    EasyUI项目管理框架,如图: 项目名称:微信管理平台 项目地址:http://www.cnblogs.com/hanyinglong/p/3236966.html#3007557 托管地址:htt ...