package _02分类算法._03链表;
import java.util.Stack;
/*
判断一个链表是否为回文结构(三种方式)
【题目】 给定一个链表的头节点head,请判断该链表是否为回文结构。
例如: 1->2->1,返回true。
1->2->2->1,返回true。
15->6->15,返回true。
1->2->3,返回false。
进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)
思路1:(空间复杂度n)将链表从头结点依次放到栈中,放完后,每次从栈中取出一个元素和链表比较,如果不相等返回false
都相等则返回true
思路2:一个快指针一个慢指针,找到链表的中点
*/
public class _02判断链表是否为回文 {
public static class Node {
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
//方法一:需要O(n)的额外空间
public static boolean isPalindrome1(Node head) {
//创建一个栈对象
Stack<Node> stack = new Stack<Node>();
Node cur = head; //head指针不能变因为后面还要用到
//将链表中的所有元素都装到栈中
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
//将栈中的元素依次拿出来与链表的元素对比,如果存在不同的书名不是回文
while (head != null) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
//方法二:需要n/2的额外空间
public static boolean isPalindrome2(Node head) {
//没有元素和只有一个元素时直接返回true
if (head == null || head.next == null) {
return true;
}
//定义一个快指针cur一个慢指针right,当cur走到头时right正好处在中间的位置(然后只将右半部分压入栈中,节约一半的空间)
Node right = head.next; //慢指针提前一步123->3 1234->3
Node cur = head; //块指针再起点
while (cur.next != null && cur.next.next != null) {
right = right.next;
cur = cur.next.next;
}
//创建栈,将右半部分装进去
Stack<Node> stack = new Stack<Node>();
while (right != null) {
stack.push(right);
right = right.next;
}
while (!stack.isEmpty()) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
//方法三:需要O(1)的额外空间
public static boolean isPalindrome3(Node head) {
if (head == null || head.next == null) {
return true;
}
Node n1 = head; //慢指针提前一步123->2 1234->2
Node n2 = head;
while (n2.next != null && n2.next.next != null) { // find mid node
n1 = n1.next; // n1 -> mid
n2 = n2.next.next; // n2 -> end
}
n2 = n1.next; // n2 -> right part first node
n1.next = null; // mid.next -> null
Node n3 = null;
while (n2 != null) { // right part convert
n3 = n2.next; // n3 -> save next node
n2.next = n1; // next of right node convert
n1 = n2; // n1 move
n2 = n3; // n2 move
}
n3 = n1; // n3 -> save last node
n2 = head;// n2 -> left first node
boolean res = true;
while (n1 != null && n2 != null) { // check palindrome
if (n1.value != n2.value) {
res = false;
break;
}
n1 = n1.next; // left to mid
n2 = n2.next; // right to mid
}
n1 = n3.next;
n3.next = null;
while (n1 != null) { // recover list
n2 = n1.next;
n1.next = n3;
n3 = n1;
n1 = n2;
}
return res;
}
//打印列表元素的工具类
public static void printLinkedList(Node node) {
System.out.print("Linked List: ");
while (node != null) {
System.out.print(node.value + " ");
node = node.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head = null;
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
}
}
//工具类-----工具类-------工具类------工具类------工具类---------工具类------------工具类-------------工具类-------工具类---
没有合适的资源?快使用搜索试试~ 我知道了~
此仓库存储的是数据结构与经典算法.zip
共246个文件
java:233个
xml:11个
iml:1个
需积分: 2 0 下载量 37 浏览量
2024-01-14
12:41:32
上传
评论
收藏 305KB ZIP 举报
温馨提示
算法与数据结构它们分别涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法: 算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。
资源推荐
资源详情
资源评论
收起资源包目录
此仓库存储的是数据结构与经典算法.zip (246个子文件)
.gitignore 25B
AlgorithmProject.iml 855B
_02判断链表是否为回文.java 6KB
_03二叉树的序列化与反序列化.java 6KB
_05两个单链表相交的问题.java 6KB
_10单调栈结构应用之生成二叉树.java 5KB
_03单向链表的荷兰国旗问题.java 5KB
_01KMP算法.java 5KB
_00二叉树.java 5KB
_06_BFPRT算法.java 5KB
_04复制随机指针节点的链表.java 4KB
_01java内置的数据结构.java 4KB
_08猫狗队列.java 4KB
_03前缀树.java 4KB
Code_06_BFPRT.java 4KB
_04_Manacher算法之算法解.java 4KB
_01查找二叉树的后继节点.java 4KB
_04_Manacher算法之暴力解.java 4KB
_06环形单链表的约瑟夫问题.java 4KB
_03得到一棵树的最大搜岁二叉子树.java 4KB
_01并查集.java 3KB
_05_Manacher应用之_添加字符串使成回文.java 3KB
_01打印两个有序链表的公共部分.java 3KB
_19顺时针打印矩阵88.java 3KB
_02查找二叉树的前驱节点.java 3KB
_17树的字结构88.java 3KB
_07判断是否为完全二叉树.java 3KB
_28全排列_字符串_字典序法.java 3KB
_11单调栈结构应用之求最大子矩阵.java 3KB
_02棵树的最大值和最小值_递归法.java 3KB
_58二叉树的下一个结点88.java 3KB
_62序列化二叉树_层次.java 3KB
_60按之字形顺序打印二叉树.java 3KB
_07字符串匹配问题_正则表达式.java 3KB
_07滑动窗口问题.java 3KB
_59对称的二叉树88.java 3KB
_03纸牌博弈问题_暴力.java 3KB
_04两个有序数组的中位数.java 3KB
_08滑动窗口之应用子数组最大值与最小值.java 3KB
_24二叉树中和为某一值的路径88.java 3KB
_05二叉树两个节点的最大距离.java 3KB
_03排序相邻最大差值.java 3KB
_3积木搭铁塔.java 3KB
_02累加和小于等于指定值的最长子数组长度_3.java 3KB
_09N皇后问题.java 3KB
_01单链表.java 3KB
_61把二叉树打印成多行.java 3KB
_02大数相乘.java 3KB
_02KMP应用之_添加字符串.java 3KB
_36数组中的逆序对88.java 3KB
_01MyHashMap.java 3KB
_02升级版旋转矩阵.java 3KB
_05判断是否为平衡二叉树.java 3KB
_04判断是否为平衡二叉树.java 3KB
_09摊牌找顺序.java 3KB
_10N皇后问题_位运算解法.java 3KB
_62序列化二叉树_先序.java 3KB
_53正则表达式匹配88.java 3KB
_04用数组实现队列和栈.java 3KB
_06旋转数组的最小数字.java 3KB
_04折纸问题.java 3KB
_04重建二叉树88.java 3KB
_12二叉树的右视图.java 3KB
_34丑数88.java 2KB
_02累加和为指定值的最长子数组长度_1.java 2KB
_11S型打印二叉树节点.java 2KB
_02对数器.java 2KB
_02岛问题.java 2KB
_07数组_公司晚会活跃度.java 2KB
_04数组_公司晚会活跃度.java 2KB
_57删除链表中重复的结点.java 2KB
_27全排列_字符串_暴力解.java 2KB
_00对数器.java 2KB
_01升级版旋转矩阵.java 2KB
_14二叉树的左视图_0.java 2KB
_03之字形打印矩阵.java 2KB
_06多叉树_公司晚会活跃度.java 2KB
_09单调栈结构.java 2KB
_02二叉树_直观打印.java 2KB
_09二叉树的Morris遍历.java 2KB
_01数组中的逆序对.java 2KB
_03二叉树的Morris遍历.java 2KB
_04排好序的矩阵中找数.java 2KB
_02累加和为指定值的最长子数组长度_2.java 2KB
_15利用堆结构来实现中位树的查找.java 2KB
_18二叉树的镜像.java 2KB
_01三个线程循环打印.java 2KB
_09_n乘m的方块中的最小路径和.java 2KB
_07页面缓存算法LRU.java 2KB
_10获取二叉树的高度.java 2KB
_07栈结构实现队列.java 2KB
Code_03_KMP_T1SubtreeEqualsT2.java 2KB
_47孩子们的游戏_圆圈中最后剩下的数88.java 2KB
_01转圈打印矩阵.java 2KB
_02两数相加.java 2KB
_1严格升序排列.java 2KB
_09堆排序.java 2KB
_02RandomPool.java 2KB
_07_01背包问题.java 2KB
_12两个字符串的最长公共子序列.java 2KB
共 246 条
- 1
- 2
- 3
资源评论
极致人生-010
- 粉丝: 2975
- 资源: 2825
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功