zoukankan      html  css  js  c++  java
  • 链表回文串判断&&链式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;
    }
    };
  • 相关阅读:
    二分图最大匹配的K&#246;nig定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/5462689.html
Copyright © 2011-2022 走看看