algorithm-base/animation-simulation/链表篇/234. 回文链表.md

461 lines
15 KiB
Java
Raw Normal View History

2021-03-20 08:57:12 +00:00
> **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
>
>
> <u>[****](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
#### [234. ](https://leetcode-cn.com/problems/palindrome-linked-list/)
2021-03-19 07:07:33 +00:00
1:
```
: 1->2
: false
```
2:
```java
: 1->2->2->1
: true
```
O(1)O(n)
2021-04-28 10:28:00 +00:00
****
2021-07-12 12:25:03 +00:00
Java Code:
2021-03-19 07:07:33 +00:00
```java
class Solution {
public boolean isPalindrome(ListNode head) {
//这里需要用动态数组,因为我们不知道链表的长度
List<Integer> arr = new ArrayList<Integer>();
ListNode copynode = head;
//将链表的值复制到数组中
while (copynode != null) {
arr.add(copynode.val);
copynode = copynode.next;
}
2021-07-12 12:25:03 +00:00
//双指针遍历数组
2021-03-19 07:07:33 +00:00
int back = 0;
int pro = arr.size() - 1;
while (back < pro) {
//判断两个指针的值是否相等
if (!arr.get(pro).equals(arr.get(back))) {
return false;
}
//移动指针
back++;
pro--;
}
return true;
}
}
```
2021-07-12 12:25:03 +00:00
C++ Code:
```cpp
class Solution {
public:
bool isPalindrome(ListNode* head) {
2021-07-15 16:06:52 +00:00
//这里需要用动态数组,因为我们不知道链表的长度
2021-07-12 12:25:03 +00:00
vector<int> arr;
ListNode* copynode = head;
2021-07-15 16:06:52 +00:00
//将链表的值复制到数组中
2021-07-12 12:25:03 +00:00
while (copynode) {
arr.push_back(copynode->val);
copynode = copynode->next;
}
2021-07-15 16:06:52 +00:00
//双指针遍历数组
2021-07-12 12:25:03 +00:00
int back = 0;
int pro = arr.size() - 1;
while (back < pro) {
2021-07-15 16:06:52 +00:00
//判断两个指针的值是否相等
2021-07-12 12:25:03 +00:00
if (arr[back] != arr[pro]) {
return false;
}
2021-07-15 16:06:52 +00:00
//移动指针
2021-07-12 12:25:03 +00:00
back++;
pro--;
}
return true;
}
};
```
JS Code:
```js
var isPalindrome = function(head) {
let arr = [];
let copynode = head;
//将链表的值复制到数组中
while (copynode) {
arr.push(copynode.val)
copynode = copynode.next
}
//双指针遍历数组
let back = 0;
let pro = arr.length - 1;
while (back < pro) {
//判断两个指针的值是否相等
if (arr[back] !== arr[pro]) {
return false
}
//移动指针
back += 1
pro -= 1
}
return true
};
```
Python Code:
2021-07-15 16:06:52 +00:00
```python
2021-07-12 12:25:03 +00:00
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
arr = []
copynode = head
#
while copynode is not None:
arr.append(copynode.val)
copynode = copynode.next
#
back = 0
pro = len(arr) - 1
while back < pro:
#
if arr[back] != arr[pro]:
return False
#
back += 1
pro -= 1
return True
```
2021-07-17 14:28:06 +00:00
Swift Code
```swift
class Solution {
func isPalindrome(_ head: ListNode?) -> Bool {
// 这里需要用动态数组,因为我们不知道链表的长度
var arr:[Int?] = []
var copynode = head
// 将链表的值复制到数组中
while copynode != nil {
arr.append(copynode?.val)
copynode = copynode?.next
}
// 双指针遍历数组
var back = 0, pro = arr.count - 1
while back < pro {
// 判断两个指针的值是否相等
if arr[pro] != arr[back] {
return false
}
// 移动指针
back += 1
pro -= 1
}
return true
}
}
```
2021-03-19 07:07:33 +00:00
2021-07-15 16:06:52 +00:00
****
2021-03-19 07:07:33 +00:00
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/翻转链表部分.1v2ncl72ligw.gif)
2021-04-28 10:28:00 +00:00
#### ****
Java Code
2021-03-19 07:07:33 +00:00
```java
class Solution {
public boolean isPalindrome(ListNode head) {
if (head==null || head.next==null) {
return true;
2021-03-19 07:07:33 +00:00
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
2021-07-15 16:06:52 +00:00
ListNode midnode = searchmidnode(head);
2021-03-19 07:07:33 +00:00
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
2021-07-15 16:06:52 +00:00
ListNode backhalf = reverse(midnode.next);
2021-03-19 07:07:33 +00:00
//遍历两部分链表,判断值是否相等
ListNode p1 = head;
ListNode p2 = backhalf;
while (p2 != null) {
if (p1.val != p2.val) {
//若要还原记得这里也要reverse
2021-07-15 16:06:52 +00:00
midnode.next = reverse(backhalf);
return false;
2021-03-19 07:07:33 +00:00
}
p1 = p1.next;
p2 = p2.next;
}
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
2021-03-19 07:07:33 +00:00
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
2021-07-15 16:06:52 +00:00
midnode.next = reverse(backhalf);
2021-03-19 07:07:33 +00:00
return true;
}
//找到中点
public ListNode searchmidnode (ListNode head) {
ListNode fast = head;
ListNode slow = head;
2021-03-19 07:07:33 +00:00
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
//翻转链表
public ListNode reverse (ListNode slow) {
ListNode low = null;
ListNode temp = null;
while (slow != null) {
temp = slow.next;
slow.next = low;
low = slow;
slow = temp;
2021-03-19 07:07:33 +00:00
}
return low;
}
}
```
2021-04-28 10:28:00 +00:00
C++ Code
```cpp
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return true;
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
2021-04-28 10:28:00 +00:00
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
2021-07-15 16:06:52 +00:00
ListNode * midnode = searchmidnode(head);
2021-04-28 10:28:00 +00:00
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode->next需要注意因为我们找到的是中点但是我们翻转的是后半部分
2021-07-15 16:06:52 +00:00
ListNode * backhalf = reverse(midnode->next);
2021-04-28 10:28:00 +00:00
//遍历两部分链表,判断值是否相等
ListNode * p1 = head;
ListNode * p2 = backhalf;
while (p2 != nullptr) {
if (p1->val != p2->val) {
//若要还原记得这里也要reverse
2021-07-15 16:06:52 +00:00
midnode->next = reverse(backhalf);
return false;
2021-04-28 10:28:00 +00:00
}
p1 = p1->next;
p2 = p2->next;
}
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
2021-04-28 10:28:00 +00:00
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
2021-07-15 16:06:52 +00:00
midnode->next = reverse(backhalf);
2021-04-28 10:28:00 +00:00
return true;
}
//找到中间的部分
ListNode * searchmidnode (ListNode * head) {
ListNode * fast = head;
ListNode * slow = head;
2021-04-28 10:28:00 +00:00
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
//翻转链表
ListNode * reverse (ListNode * slow) {
ListNode * low = nullptr;
ListNode * temp = nullptr;
while (slow != nullptr) {
temp = slow->next;
slow->next = low;
low = slow;
slow = temp;
2021-04-28 10:28:00 +00:00
}
return low;
}
};
```
JS Code:
```javascript
var isPalindrome = function(head) {
if (head === null || head.next === null) {
return true;
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
2021-07-15 16:06:52 +00:00
let midnode = searchmidnode(head);
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
2021-07-15 16:06:52 +00:00
let backhalf = reverse(midnode.next);
//遍历两部分链表,判断值是否相等
let p1 = head;
let p2 = backhalf;
while (p2 != null) {
if (p1.val != p2.val) {
//若要还原记得这里也要reverse
2021-07-15 16:06:52 +00:00
midnode.next = reverse(backhalf);
return false;
}
p1 = p1.next;
p2 = p2.next;
}
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
2021-07-15 16:06:52 +00:00
midnode.next = reverse(backhalf);
return true;
};
//找到中点
var searchmidnode = function(head) {
let fast = head;
let slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
};
//翻转链表
var reverse = function(slow) {
let low = null;
let temp = null;
while (slow != null) {
temp = slow.next;
slow.next = low;
low = slow;
slow = temp;
}
return low;
};
```
Python Code:
2021-07-15 16:06:52 +00:00
```python
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if head is None or head.next is None:
return True
#
#
midnode = self.searchmidnode(head)
#
# midnode.next
backhalf = self.reverse(midnode.next)
#
p1 = head
p2 = backhalf
while p2 is not None:
if p1.val != p2.val:
# reverse
midnode.next = self.reverse(backhalf)
return False
p1 = p1.next
p2 = p2.next
#
2021-07-15 16:06:52 +00:00
# AC
midnode.next = self.reverse(backhalf)
return True
#
def searchmidnode(self, head):
fast = head
slow = head
while fast.next is not None and fast.next.next is not None:
fast = fast.next.next
slow = slow.next
return slow
#
def reverse(self, slow):
low = None
temp = None
while slow is not None:
temp = slow.next
slow.next = low
low = slow
slow = temp
return low
```
2021-07-17 14:28:06 +00:00
Swift Code
```swift
class Solution {
func isPalindrome(_ head: ListNode?) -> Bool {
if head == nil || head?.next == nil {
return true
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
var midnode = searchmidnode(head)
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
var backhalf = reverse(midnode?.next);
//遍历两部分链表,判断值是否相等
var p1 = head
var p2 = backhalf
while p2 != nil {
if p1?.val != p2?.val {
midnode?.next = reverse(backhalf)
return false
}
p1 = p1?.next
p2 = p2?.next
}
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
midnode?.next = reverse(backhalf)
return true
}
//找到中点
func searchmidnode(_ head: ListNode?) -> ListNode? {
var fast = head, slow = head
while fast?.next != nil && fast?.next?.next != nil {
fast = fast?.next?.next
slow = slow?.next
}
return slow
}
//翻转链表
func reverse(_ slow: ListNode?) -> ListNode? {
var slow = slow
var low: ListNode?
var temp: ListNode?
while slow != nil {
temp = slow?.next
slow?.next = low
low = slow
slow = temp
}
return low
}
}
```