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

来源:互联网 发布:网络专供和实体店区别 编辑:程序博客网 时间:2024/05/22 10:31
有段时间没有练习了,链表回文串判断用到了栈。链式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。
《程序员面试金典》程序详解:
http://blog.csdn.net/zdplife/article/category/5799903
/****************************************************** \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 hereListNode *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;}};

  这个哥们总结的不错:

《程序员面试金典》程序详解:
http://blog.csdn.net/zdplife/article/category/5799903

题目描述

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

给定两个链表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;}};

 

0 0
原创粉丝点击