• 链表回文串判断&&链式A+B


    有段时间没有练习了,链表回文串判断用到了栈。链式A+B将没有的项用0补充。链表有没有头节点,及结点和链表的区别,即pNode和pHead。

    //#include<iostream>
    //using namespace std;
    //
    //class Base {
    //public:
    //	Base(int j) : i(j)  {}
    //	virtual~Base() {}
    //	void func1() {
    //		i *= 10;
    //		func2();
    //	}
    //	int getValue() {
    //		return  i;
    //	}
    //protected:
    //	virtual void func2() {
    //		i++;
    //	}
    //protected:
    //	int i;
    //};
    //
    //class Child : public Base {
    //public:
    //	Child(int j) : Base(j) {}
    //	void func1() {
    //		i *= 100;
    //		func2();
    //	}
    //protected:
    //	void func2() {
    //		i += 2;
    //	}
    //};
    //int main() {
    //	Base * pb = new Child(1);
    //	pb->func1();
    //	cout << pb->getValue() << endl;  ///12
    //	delete pb;
    //}
    

    题目分析:

    《方法1》:反转链表

           可以将原始链表反转,判断反转以后的链表与原始链表是否完全一致,如果一致便返回true,如果不一致则返回false。反转链表需要额外的存储空间,不是特别优秀的方法。

    《方法2》:栈实现

           我们可以想到从中间节点向两侧开始比较,如果全部相同,则返回true,否则返回false,因为无法获得一个节点的前一个节点,这个时候我们可以想到用栈实现,先将链表前半部分的元素分别压入堆栈,然后在遍历后半部分元素的时候同时和栈顶元素进行比较,如果全部相等则返回true,否则返回false。

          特别注意:因为我们不知道链表的的长度,可以通过快慢指针(一个指针每次移动两个,一个指针每次移动一个)来找到中间元素,这样整体只需要遍历链表一次,所需要的栈空间缩小为方法1的一半。

    《方法3》:递归法

           递归方法分为尾部递归和首部递归,还有中间递归,一般的尾部递归都可以用循环来实现,对于我们这道题目,递归的时候无法比较第一个元素和最后一个元素,即使知道最后一个元素,也无法获得最后一个元素的前一个元素。所以我们选择首部递归,先递归直到中间的元素,然后比较中间的元素,把比较结果返回,同时保存后半部分下一个要比较的元素(用引用传递可以,用二级指针也可以),递归返回后,如果是true,则继续比较,如果是false,则直接返回false。
    《程序员面试金典》程序详解:
    /*****************************************************
    * file Palindrome listNode.cpp
    * date 2016/05/05 17:16
    
    题目描述
    
    请编写一个函数,检查链表是否为回文。
    给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
    测试样例:
    {1,2,3,2,1}
    返回:true
    {1,2,3,2,3}
    
    返回:false
    
    *****************************************************/
    
    struct ListNode
    {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :val(x), next(nullptr){}
    };
    
    
    #include <iostream>
    #include <stack>
    using namespace std;
    
    class Palindrome {
    public:
    	bool isPalindrome(ListNode* pHead) {
    		// write code here
    		ListNode *pNode = pHead;
    		stack<int> s;
    		while (pNode)
    		{
    			s.push(pNode->val);
    			pNode = pNode->next;
    		}
    		pNode = pHead;
    		while (pNode)
    		{
    			if (pNode->val==s.top())
    			{
    				pNode=pNode->next;
    				s.pop();
    			}
    			else
    			{
    				return false;
    			}
    		}
    		return true;
    	}
    };
    

      这个哥们总结的不错:

    《程序员面试金典》程序详解:

    题目描述

    有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。

    给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。

    测试样例:
    {1,2,3},{3,2,1}
    返回:{4,4,4}
    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) : val(x), next(NULL) {}
    };*/
    class Plus {
    public:
       ListNode* plusAB(ListNode* a, ListNode* b) {
        int carry = 0;
        ListNode *retHead = new ListNode(0);
        ListNode *p = retHead;
        while (a || b || carry) {
            int vala = a ? a->val : 0;
            int valb = b ? b->val : 0;
            int val = (vala + valb + carry) % 10;
            carry = (vala + valb + carry) / 10;  //进位
            ListNode *tmp = new ListNode(val);
            p->next = tmp;
            p = p->next;
            a = a ? a->next : nullptr;
            b = b ? b->next : nullptr;
        }
        p->next = nullptr;
        return retHead->next;
    }
    };
  • 相关阅读:
    vue 分页 pagination
    查看android 签名文件keystore的有效期限
    cordova + vue 项目实现极光推送功能
    vue window
    input
    vue install 组件
    cordova 的安桌动画
    深度图
    css3 Transition动画执行时有可能会出现闪烁的bug
    windows zip命令
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/5462689.html
Copyright © 2020-2023  润新知