[LeetCode] Palindrome Linked List

Given a singly linked list, determine if it is a palindrome.

一开始想用栈,但是试来试去发现写不出来遂放弃,后来想想再不济可以转换成数组然后分别两头扫,但是这样就用了O(n) 的空间,再进一步,可不可以在链表里模拟呢。思前想后发现是可以的,只要把链表的头尾接到一起形成个环,然后头指针每次一动1步,尾指针每次移动 len - 1 步就行了,len 是链表的长度。

这样我实现了算法1:

/*** Definition for singly-linked list.* function ListNode(val) {*     this.val = val;*     this.next = null;* }*/
/*** @param {ListNode} head* @return {boolean}*/
var isPalindrome = function(head) {if (!head) return true;var tail = head;var len = 0;while (tail && tail.next) {len++;tail = tail.next;}len++;tail.next = head;var ring = len;while (tail.val == head.val) {if (tail === head || ring === 0) return true;head = head.next;ring--;for (var i = 0; i < len - 1; i++) {tail = tail.next;}}return false;
};

这个算法是正确的,但是很遗憾TLE 了。头尾相接的做法其实是用取模运算的原理来模拟指针运动,可以运用相同原理适当改写程序而避免头尾相接,算法2:

/*** @param {ListNode} head* @return {boolean}*/
var isPalindrome = function(head) {if (!head) return true;var tail = head;var len = 0;while (tail && tail.next) {len++;tail = tail.next;}len++;var p1 = head;var p2 = head;var k = 1;for (var i = 0; i < len - k; i++) {p2 = p2.next;}while (p1 && p2 && p1.val == p2.val) {if (p1 === p2 || k == len) return true;k++;p2 = head;for (var i = 0; i < len - k; i++) {p2 = p2.next;}p1 = p1.next;}return false;
};

算法1,2 的区别就是有卵用和没卵用的区别,但是貌似头尾相接要更简洁一点,但是同样是TLE。

后面看了些提示又想出一个土办法:可以copy 一个链表出来然后反转,然后两个链表一起遍历对比,算法3:

/*** Definition for singly-linked list.* function ListNode(val) {*     this.val = val;*     this.next = null;* }*/
/*** @param {ListNode} head* @return {boolean}*/
var reverseList = function(head) {if (!head) return null;var prev = null;var now = head;var next = head.nextwhile (now) {now.next = prev;prev = now;now = next;if (next) next = next.next;}return prev;
};var copyList = function(head) {var p = new ListNode(-1);var c = p;while (head) {var n = new ListNode(head.val);c.next = n;c = n;head = head.next;}return p.next;
}var isPalindrome = function(head) {if (!head) return true;var copy = copyList(head);var rev = reverseList(copy);var p = rev;var q = head;while (p && q) {if (p.val !== q.val) return false;p = p.next;q = q.next;}return true;
};

这个是可以accept 的,但是是用了O(n) 额外空间,那么转换成数组或者字符串两头扫八成也是可以通过的。

最后看了一些答案,发现虽然翻转整个链表需要O(n)的额外空间,但是翻转一半的话就不需要,那么只需要把原链表翻转一半,然后两头扫就行,关键是怎么找到一半。

要么先扫一遍得到长度,再扫一遍取一半。但是有更简洁的办法可以一次遍历就找出中点,就是快慢指针。设想一个指针按正常速度遍历链表,另一个指针的速度是他的一半,那么当正常速度指针遍历结束的时候,半速指针刚好在链表的中间,利用这个技巧找到链表中点,然后从中点开始翻转,然后两头扫就可以。算法4:

/*** Definition for singly-linked list.* function ListNode(val) {*     this.val = val;*     this.next = null;* }*/
/*** @param {ListNode} head* @return {boolean}*/
var reverseList = function(head) {if (!head) return null;var prev = null;var now = head;var next = head.nextwhile (now) {now.next = prev;prev = now;now = next;if (next) next = next.next;}return prev;
};var isPalindrome = function(head) {if (!head) return true;var fast = head;var slow = head;var m = 1;while (fast) {if (m === 0) {slow = slow.next;}m = (m + 1) % 2;fast = fast.next;}var tail = reverseList(slow);while (head && tail) {if (head.val !== tail.val) return false;head = head.next;tail = tail.next;}return true;};

利用一个整数变量m 来控制slow 指针的速度,fast 每走两步,slow走一步。然后reverse 另一半,两头扫。整个过程还是很简洁的,Accepted。

转载于:https://www.cnblogs.com/agentgamer/p/4907848.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【原创】Ajax的用法总结

一、什么是AjaxAjax英文全称为“ Asynchr JavsScript and XML”&#xff08;异步的JavaScript和XML&#xff09;&#xff0c;是一种创建交互式网页的开发技术。二、Ajax技术的核心Ajax是一系列相关技术的融合&#xff0c;其核心包括XMLHttpRequest、JavsScript和DOM技术&#x…

gprs java_WISMO模块GPRS上网设置的过程

WISMO模块GPRS上网设置的过程一) AT指令设置部分(1) ATCGCLASS“B”置为“网络WISMO模块GPRS上网设置的过程一) AT指令设置部分(1) ATCGCLASS“B”置为“B”模式。(2) ATCGDCONT1&#xff0c;“IP”&#xff0c;“CMNET”设置APN。(3) ATCSQ 检查信号 若返回10—31&#xff0c…

loadrunner性能测试步骤

性能测试过程分为4个阶段&#xff1a;设计、构建、执行、分析/诊断/调节具体的工作流程如下图 设计  >  构建  >  执行   >  分析/诊断/调节 收集要求    设置测试环境 基准测试    诊断瓶颈 设计测试策略  记录测试脚本 性能测试     调…

Asp.Net生命周期的详解

一&#xff0e;Asp.Net页面生命周期的概念当我们在浏览器地址栏中输入网址&#xff0c;回车查看页面时&#xff0c;这时会向服务器端IIS&#xff09;发送一个request请求&#xff0c;服务器就会判断发送过来的请求页面&#xff0c;当完全识别 TTP页面处理程序类后&#xff0c;A…

java chain_java 8中 predicate chain的使用

java 8中 predicate chain的使用简介Predicate是一个FunctionalInterface&#xff0c;代表的方法需要输入一个参数&#xff0c;返回boolean类型。通常用在stream的filter中&#xff0c;表示是否满足过滤条件。boolean test(T t);基本使用我们先看下在stream的filter中怎么使用P…

前段技术学习计划

资料&#xff1a; 著作权归作者所有。 商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 作者&#xff1a;陈禹鲁 链接&#xff1a;http://www.zhihu.com/question/19809484/answer/35544452 来源&#xff1a;知乎 第一本&#xff0c;入门 《Head first HTML&…

指针的概念

在C语言中&#xff0c;内存单元的地址称为指针&#xff0c;专门用来存放地址的变量&#xff0c;有时对地址&#xff0c;指针和指针变量不区分&#xff0c;统称指针。&#xff08;地址指针&#xff09; 一般情况下&#xff0c;最前面的存储类型通常会省略 指针在说明的同时&…

整理一些提高C#编程性能的技巧

1、使用StringBuilder代替使用string 连接符 ""说明&#xff1a;String类对象是不可变的&#xff08;只读&#xff09;&#xff0c;一旦创建该对象&#xff0c;就不能修改该对象的值。对象String对象的重新赋值&#xff0c;本质上是重新创建了一个String对象并将新的…

python爬知识星球付费数据_用python爬取知识星球

去年我们做过一个叫「学长问答」的社群活动&#xff0c;里面沉淀了大量有价值的互动信息&#xff0c;后来因为各种原因终止了。今天和涂腾聊起来&#xff0c;觉得这些信息就这么沉寂了太浪费。所以就试着用python爬取了知识星球的内容。这个过程又学习了一些新的知识&#xff0…

HTML学习(1)

1、缩写和首字母缩写<abbr><acronym> <abbr title"etcetera">etc.</abbr> <acronym title"World Wide Web">WWW</acronym> 2、块引用&#xff08;短&#xff09; <p>A: <q>B</q>C</p> 显示结…

常用的7个SQl优化技巧

作为程序员经常和数据库打交道的时候还是非常频繁的&#xff0c;掌握住一些Sql的优化技巧还是非常有必要的。下面列出一些常用的SQl优化技巧&#xff0c;感兴趣的朋友可以了解一下。1、注意通配符中Like的使用以下写法会造成全表的扫描&#xff0c;例如&#xff1a;select id,n…

toolbar java_Java ToolBar.layout方法代码示例

import org.eclipse.swt.widgets.ToolBar; //导入方法依赖的package包/类protected ToolBar createToolbar() {final ToolBar t new ToolBar(composite, SWT.FLAT | SWT.LEFT | SWT.HORIZONTAL | SWT.WRAP);final GridData d new GridData(SWT.FILL, SWT.TOP, false, false);…

Visual Studio常用的快捷键整理

微软的开发工具Visual Studio作为DoNet开发者来说是必备神器&#xff0c;该开发工具内置了很多的开发快捷键&#xff0c;熟悉了这些开发快捷键&#xff0c;对于程序员来说事半功倍&#xff0c;所以在这里整理一下&#xff0c;版本是vs2012以上&#xff0c;目前小编列出了自己觉…

win7旗舰版6l打印机咋安驱动_在w7旗舰版上怎么安装HPlaserjet6L打印机?

您好&#xff0c;感谢您选择惠普产品。首先6L产品只有并口线&#xff0c;但是现在win 7 电脑基本都没有并口&#xff0c;有可能是您使用了转接usb设备&#xff0c;但是产品在出厂的时候会对产品作测试&#xff0c;测试的结果是不建议使用转接设备或者是延长设备&#xff0c;以免…

收集一些工作中常用的经典SQL语句

作为一枚程序员来说和数据库打交道是不可避免的&#xff0c;现收集一下工作中常用的SQL语句&#xff0c;希望能给大家带来一些帮助&#xff0c;当然可能不全面&#xff0c;欢迎补充&#xff01;1、执行插入语句&#xff0c;获取自动生成的递增的ID值INSERT INTO SysRole (RoleN…

ascii modbus vc源码_MODBUS ASCII及MODBUS RTU通讯

代码片段和文件信息using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.IO.Ports;//串口using…

Asp.Net操作Cookie总结

一、什么是Cookie&#xff1f;Cookie是存储在客户端文件系统的文本文件或客户端浏览器对话的内存中的少量数据。它主要用来跟踪数据设置&#xff0c;例如&#xff1a;当我们要访问一个网站网页的时候&#xff0c;用户请求网页时&#xff0c;应用程序可能会首先检查此用户是否已…

java GUI怎么输入_在Swing中创建Java GUI以进行表单输入

好吧,我已经浏览了整个互联网,但却未能找到这个问题的答案,所以也许有人可以提供一些见解.我正在开发一个相对简单的Java应用程序,它将取代目前用于系统访问请求的Word文档.它旨在允许表单输入新的员工雇用信息 – 名称,所需的访问权限等.所以这是我的问题.尝试使用所有文本字段…

Net中Session的用法

一、什么是Session&#xff1f;简单来说&#xff0c;就是用户与网站服务器建立的一个连接&#xff0c;服务器分配给一个编号。当一台WWW服务器运行时&#xff0c;可能有若干用户正在浏览运行在这台服务器上的网站。当用户首次与这台WWW服务器创建连接的时候&#xff0c;它就和这…

关于Json的总结

一、什么是Json&#xff1f;JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。它是基于 JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999的一个子集。 JS…