版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qibofang/article/details/51924834
题目描述:给定一个字符串,判断该字符串是否为回文字符串,是则返回true,否则返回false。所谓回文串是指字符串从前往后读,以及从后往前读,结果一致,如:madam, 12344321等
解法1:从两头往中间扫,定义两个指针,分别指向字符串的头和尾,并分别向前和向后移动,依次判断对应元素是否都相同。时间复杂度为O(n),空间复杂度为O(1)。
#include <iostream>
#include <string>
using namespace std;
bool IsPalindrome(string &str){
int len = str.size();
if(len == 0)
return false; //空串返回false
int start = 0, end = str.size()-1;
while(start < end){
if(str[start] != str[end])
return false;
++start;
--end;
}
return true;
}
int main(){
string str;
while(cin >> str){
if(IsPalindrome(str))
cout << "true\n";
else
cout << "false\n";
}
return 0;
}
解法2:从中间往两头扫,定义两个指针,先判断字符串字符个数,奇数则将两个指针指向字符串正中间那个元素,偶数则将两个指针指向字符串正中间的那两个元素,然后相背移动,依次比较对应元素看是否都相等(可以随便以一个字符串比划一下,应该能够包含所有的情况)。时间复杂度为O(n),空间复杂度为O(1)。
#include <iostream>
#include <string>
using namespace std;
bool IsPalindrome(string &str){
int len = str.size();
if(len == 0)
return false; //空串返回false
int left, right;
if(len % 2 == 1){ //根据字符串中字符的个数来对两个指针进行初始化定位
left = len / 2; right = len / 2;
}
else{
left = len / 2 - 1; right = len / 2;
}
while(left >= 0){
if(str[left] != str[right])
return false;
--left;
++right;
}
return true;
}
int main(){
string str;
while(cin >> str){
if(IsPalindrome(str))
cout << "true\n";
else
cout << "false\n";
}
return 0;
}
链表回文:判断一条单向链表是不是回文
解法:先输入一个字符串,将其构成单链表。之后,可先定位到链表的中间位置,再将链表的后半段逆置。之后使用两个指针同时从链表头部和中间开始逐一向后遍历比较。时间复杂度为O(n),空间复杂度为O(1)。
单链表尾插法或翻转的图示如下:
#include <iostream>
#include <string>
using namespace std;
struct Node{
char data;
Node *next;
};
Node * CreateList(string &str){
Node *tmp, *head = NULL;
if(str.size() == 0)
return head;
//字符串长为0则直接返回,否则先构建一个node,再组建整个链表
head = (Node *)malloc(sizeof(Node));
head->data = str[0];
int i;
Node *p = head;
for(i = 1; i < str.size(); ++i){
tmp = (Node *)malloc(sizeof(Node));
tmp->data = str[i];
p->next = tmp;//p连接到tmp
p = p->next;//p移动到下个位置
}
p->next = NULL;
return head;
}
bool ReverseListRight(Node *head, int len){
int mid, i = 0;
if(len % 2 == 1) mid = len / 2;
else mid = len / 2 - 1; //由于需要逆转后半段,故需要定位到整个后半段的前一个位置
Node *left = head, *right = head;
while(i++ < mid)
right = right->next;
//开始翻转后半段
Node *p = right->next, *q;
right->next = NULL;
while(p){//不断插入p
q = p->next;//用q保存p所指下一结点并最后赋给p
p->next = right->next;
right->next = p;
p = q;
}
//while(head){ //用来测试是否正确翻转正确
// cout << head->data;
// head = head->next;
//}
//cout << endl
//回文串判断
bool tag = true;
right = right->next;
while(right){
if(right->data != left->data)
tag = false;
right = right->next;
left = left->next;
}
if(tag)
return true;
else
return false;
}
int main(){
string str;
while(cin >> str){
Node *head = CreateList(str);
if(ReverseListRight(head, str.size()))
cout << "true\n";
else
cout << "false\n";
}
return 0;
}
栈回文:判断一个栈是不是回文
解法:将一个字符串入栈后出栈,并得到了原字符串的逆置字符串,依次比较原字符串与逆置字符串的对应下标中的数值是否相等,即原字符串:12345,出栈得到的逆置字符串:54321,故不相等。而字符串12321得到的逆置字符串12321与其相等,时间复杂度为O(n),空间复杂度为O(n)。
#include <iostream>
#include <string>
#include <stack>
using namespace std;
stack<char> sta;
bool IsPalindrome(string &str, string &ans){
int i;
for(i = 0; i < str.size(); i++)
sta.push(str[i]);
for(i = 0; i < str.size(); i++){
ans[i] = sta.top();
sta.pop();
}
for(i = 0; i < str.size(); i++)
if(ans[i] != str[i])
return false;
return true;
}
int main(){
string str, ans;
while(cin >> str){
ans = str; //需要对ans初始化,否则显示超出下标范围
if(IsPalindrome(str, ans))
cout << "true\n";
else
cout << "false\n";
}
return 0;
}