LeetCode120--反转链表、判断链表是否回文

1、反转链表

//给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
// 
// 
// 
//
// 示例 1: 
//
// 
//输入:head = [1,2,3,4,5]
//输出:[5,4,3,2,1]
// 
//
// 示例 2: 
//
// 
//输入:head = [1,2]
//输出:[2,1]
// 
//
// 示例 3: 
//
// 
//输入:head = []
//输出:[]
// 
//
// 
//
// 提示: 
//
// 
// 链表中节点的数目范围是 [0, 5000] 
// -5000 <= Node.val <= 5000 
// 
//
// 
//
// 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? 
// 
// 
// Related Topics 链表

1、迭代法 

其基本思路在于不断遍历链表,在当前元素前插入新元素,直到列表给遍历完

public ListNode reverseList(ListNode head) {
    	//迭代
			ListNode next = null;
			ListNode curr = head;
			while(curr != null){
				ListNode prev = curr.next;
				curr.next = next;
				next = curr;
				curr = prev;
			}
			return next;
}

2、递归法

递归法在于改变指向,但又不让链表中出现环

这里可以参考官方题解:

 https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/

public ListNode reverseList(ListNode head) {
		//递归
			if(head == null || head.next == null){
				return head;
			}
			ListNode newHead = reverseList(head.next);
			head.next.next = head;
			//这样就不会在链表中出现环
			head.next = null;
			return newHead;
		}

 2、判断链表是否回文

//请判断一个链表是否为回文链表。 
//
// 示例 1: 
//
// 输入: 1->2
//输出: false 
//
// 示例 2: 
//
// 输入: 1->2->2->1
//输出: true
// 
//
// 进阶: 
//你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 
// Related Topics 链表 双指针

这题的两种解法都比较一般,在这里不多加赘述

1、先转成数组再判断回文 

public boolean isPalindrome(ListNode head) {
    	//转成数组再进行回文判断
		ArrayList<Integer> vals = new ArrayList<>();
		ListNode currentNode = head;
		while(currentNode != null){
			vals.add(currentNode.val);
			currentNode = currentNode.next;
		}
		int front = 0;
		int back = vals.size()-1;
		while(front < back){
			if(!vals.get(front).equals(vals.get(back))){
				return false;
			}
			front++;
			back--;
		}
		return true;
	}

2、先用快慢指针找到中间节点,然后反转后半链表,一一对比判断是否回文,最后恢复链表。

public boolean isPalindrome(ListNode head) {
		//快慢指针法
		if(head == null){
			return true;
		}
		//1、找到前半部分链表的尾结点并反转后半部分链表
		ListNode firstHalfEnd = endofFirstHalf(head);
		ListNode secondHalfStart = reverseList(firstHalfEnd.next);
		//2、判断是否回文
		ListNode p1 = head;
		ListNode p2 = secondHalfStart;
		boolean result = true;
		while (result && p2 != null) {
			if (p1.val != p2.val) {
				result = false;
			}
			p1 = p1.next;
			p2 = p2.next;
		}
		// 还原链表并返回结果
		firstHalfEnd.next = reverseList(secondHalfStart);
		return result;
	}

	private ListNode endofFirstHalf(ListNode head) {
    	ListNode fast = head;
    	ListNode slow = head;
    	while (fast.next != null && fast.next.next != null){
    		fast = fast.next.next;
    		slow = slow.next;
		}
    	return slow;
	}

	private ListNode reverseList(ListNode head) {
		ListNode prev = null;
		ListNode curr = head;
		while (curr != null) {
			ListNode nextTemp = curr.next;
			curr.next = prev;
			prev = curr;
			curr = nextTemp;
		}
		return prev;
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值