[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.pswp.cn/news/272809.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272809.shtml
英文地址,請注明出處:http://en.pswp.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…