1.验证回文字符串 Ⅱ
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: "aba"
输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-palindrome-ii
思路:
class Solution {
public:
bool checkPalindrome(const string& s, int low, int high) {//验证是不是回文串
for(int i=low,j=high;i<j;i++,j--)
{
if(s[i]!=s[j])
return false;
}
return true;
}
bool validPalindrome(string s) {
int len=s.length();
if(len<2) return true;
int low=0,high=len-1;
while(low<high)
{
if(s[low]==s[high])
{
low++;
high--;
}//相等则继续
else
{
return checkPalindrome(s,low+1,high)||checkPalindrome(s,low,high-1);//验证[low+1,high]或[low,high-1]是不是回文串
}
}
return true;
}
};2.链表中环的入口节点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
//设置快慢指针,都从链表头出发,快指针每次走两步,慢指针一次走一步,假如有环,一定相遇于环中某点
//(结论1)。接着让两个指针分别从相遇点和链表头出发,两者都改为每次走一步,最终相遇于环入口(结论2)。
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode *fast=pHead;
ListNode *low=pHead;
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
low=low->next;
if(fast==low)
break;
}
if(fast==NULL||fast->next==NULL) return NULL;
low=pHead;
while(low!=fast)//用while更好
{
fast=fast->next;
low=low->next;
}
return low;
}
};3.删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if( pHead == nullptr ) return pHead;
ListNode *pre = nullptr; //指向前面最晚访问过的不重复结点
ListNode *p = pHead; //指向当前处理的结点
ListNode *q = nullptr; //指向当前处理结点后面结点
while( p != nullptr )
{
//当前结点p,(其实是p指向当前结点),与它下一个结点p->next的val相同,说明要删掉有这个val的所有结点
if( p->next != nullptr && p->next->val == p->val )
{
q = p->next;
//找到q,它指向最后一个与p val相同的结点,那p 到 q (包含) 都是要删除的
while( q != nullptr && q->next != nullptr && q->next->val == p->val )
{
q = q->next;
}
//如果p指向链表中第一个元素,p -> ... -> q ->... , 要删除p到q, 将指向链表第一个元素的指针pHead指向q->next。
if( p == pHead )
{
pHead = q->next;//注意这里是pHead不是p
}
else//如果p不指向链表中第一个元素,pre -> p ->...->q ->... ,要删除p到q,即pre->next = q->next
{
pre->next = q->next;
}
//当前处理的p要向链表尾部移动
p = q->next;
}
else
{
pre = p;
p = p->next;
}
}
return pHead;
}
};4.二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
//1.二叉树为空,则返回空;
/*2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点
即为下一个节点;*/
/*3.节点不存在右孩子。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,
重复之前的判断,返回结果。*/
if(pNode==NULL) return NULL;
if(pNode->right!=NULL)
{
TreeLinkNode* p=pNode->right;
while(p->left!=NULL)
p=p->left;
return p;
}
while(pNode->next!=NULL)
{
TreeLinkNode *proot=pNode->next;
if(proot->left==pNode)
return proot;
pNode=pNode->next;
}
return NULL;
}
};
京公网安备 11010502036488号