• leetcode面试题 02.06. 回文链表,解题心路


    leetcode面试题 02.06. 回文链表,解题心路

    1、题目描述

    编写一个函数,检查输入的链表是否是回文的。如图:

    试题链接:https://leetcode-cn.com/problems/palindrome-linked-list-lcci/

    2、java语言题解一

    看到该题,首先想打到的就是使用自己最拿手的语言java来做。首先,我们先来观查题目所给链表的结构:

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }
    

    由于题目中要求判断一个链表是否回文,因此很自然的一个想法就是,将链表变量,取出其中的值,放在一个有序的容器中。在java中很自然的就想到了list集合,于是就有了下述的解法:

    public static boolean isPalindrome(ListNode head) {
        List list = new ArrayList();
        //定义一个辅助指针,用来遍历链表
        ListNode pCurrent = head;
        //当链表不为null时,就一直循环
        while (pCurrent != null) {
            //将该数保存到数组中
            list.add(pCurrent.val);
            pCurrent = pCurrent.next;
        }
        //遍历集合,看首尾是否相等
        for(int i = 0;i < list.size() / 2;i++) {
            if(!list.get(i).equals(list.get(list.size() - i - 1))) {
                return false;
            }
        }
        return true;
    }
    

    算法效果:

    可以看出,该算法在java的提交记录中,时间稍微较慢,当时所需要的内存确实最少的。然而,计算机程序比较关心的是算法的执行效率,因此该算法还得进行改进。

    3、java语言题解二

    由于上述的算法的执行时间太长,猜想是不是因为使用了List集合而导致的。但是,如果不适用集合,我们的先获取到该链表的长度,然后定义一个大小刚刚适合的数组。代码如下:

    public static boolean isPalindrome(ListNode head) {
        //定义一个辅助指针,用来遍历链表
        ListNode pCurrent = head;
        //当链表不为null时,就一直循环
        int count = 0;
        while (pCurrent != null) {
            //计数
            count++;
            pCurrent = pCurrent.next;
        }
        //再来一论,装进数组
        pCurrent = head;
        int[] arr = new int[count];
        for(int i = 0;i < count;i++) {
            arr[i] = pCurrent.val;
            pCurrent = pCurrent.next;
        }
        //遍历集合,看首尾是否相等
        for(int i = 0;i < count / 2;i++) {
            if(arr[i] != arr[count - i - 1]) {
                return false;
            }
        }
        return true;
    }
    

    算法效果:

    可以看出,用数组代替集合,增加一次循环后的效率得到大幅度的提升。

    4、C语言题解一

    奈何,博主目前还是一个本科大学生,在数据结构与算法这门课上垂死挣扎,而考试只允许用C来作答,因此,只有用C语言重写上述的java算法。

    1. 先来看看在C语言中,题目给出的链表的结构题类型
    struct ListNode {
        int val;
        struct ListNode *next;
    };
    

    接下来,用C语言来实现上述的java题解二:

    bool isPalindrome(struct ListNode* head){
        //定义一个辅助指针,用来遍历链表
        struct ListNode* pCurrent = head;
        //当链表不为null时,就一直循环
        int count = 0;
        while (pCurrent != NULL) {
            //计数
            count++;
            pCurrent = pCurrent->next;
        }
        if(count == 0)
            return true;
        //再来一论,装进数组
        pCurrent = head;
        int arr[count];
        for(int i = 0;i < count;i++) {
            arr[i] = pCurrent->val;
            pCurrent = pCurrent->next;
        }
        //遍历集合,看首尾是否相等
        for(int i = 0;i < count / 2;i++) {
            if(arr[i] != arr[count - i - 1]) {
                return false;
            }
        }
        return true;
    }
    

    算法效果:

    由执行用时可以看出,在C语言的解法中,该算法并不是最优解。

    除此之外,还有另外一种思路,就是将链表拆分成两部分,然后使得一部分反转,后遍历两个链表,观察是否相等。但是,该方法经过博主测试后,发现其效率还不如上述解法高效,因此不在叙述,后续如果有新的更高效解法在来叙述。

  • 相关阅读:
    JavaScript--事件绑定及深入(26)
    JavaScript--事件对象(25)
    JavaScript--事件入门(24)
    JavaScript--动态加载脚本和样式(23)
    JavaScript--DOM元素尺寸和位置(22)
    JavaScript--DOM操作表格及样式(21)
    JavaScript--DOM进阶(20)
    jQuery-瀑布流的取巧做法分享
    Less开发指南(二)- 基本语法
    less开发指南(一)- 小牛试刀
  • 原文地址:https://www.cnblogs.com/xgp123/p/12373584.html
Copyright © 2020-2023  润新知