kim的每日刷题.LC.234. 回文链表

你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

题目要求O(1)空间复杂,而方法:数组遍历保存元素需要额外数组变量O(n)、递归回溯方式需要栈内存O(n);

一种方法是用快慢指针获得链表的中间点,然后对后半段逆序再分别比较前(正)后(逆)两段;

也可以在慢指针遍历的过程中同时对前半段逆序,然后比较前(逆)后(正)两段时间O(n),空间O(1);

Java Code:

    public static boolean isPalindrome(ListNode head) {
    	if(head == null || head.next == null) return true;
    	ListNode pre = head, prepre = head, slow = head, fast = head;
        //对前半段链表逆序
    	while(fast!=null && fast.next!=null) {
    		pre = slow;
    		slow = slow.next;
    		fast = fast.next.next;
    		pre.next = prepre;
    		prepre = pre;
    	}
    	if(fast != null)
    		slow = slow.next;
        //前后两段比较
    	while(pre!=null && slow!=null) {
    		if(pre.val!=slow.val)
    			return false;
    		slow = slow.next;
    		pre = pre.next;
    	}
    	return true;
    }

这种方法满足了题目要求,但是题目要求我们判断,而逆序操作显然修改了原链表;

但是力扣大神给出了不修改原链表,且满足时间空间复杂的奇妙方法,我愿称之为绝活(doge);

Hash Method

构造哈希函数:hash = hash * seed + val,其中seed表示一个质数,val表示节点的值;

分析回文链表的特点,我们可以得到,对于一个回文链表,其正序hash值应该等于逆序hash值

image.png

image.png

Java Code:

    public static boolean isPalindromeHash(ListNode head) {
    	if(head == null || head.next == null) return true;
    	int hash1 = 0, hash2 = 0, h = 1, seed = (int) 1e2+7;
    	while(head!=null) {
            //正序hash值
    		hash1 = hash1 * seed + head.val;
            //逆序hash值
    		hash2 = hash2 + h * head.val;
    		h *= seed;
    		head = head.next;
    	}
    	return hash1 == hash2;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值