16. 删除链表中重复的节点
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(!pHead or !pHead->next) return pHead;
//新建头节点,防止头节点重复
ListNode* Head=new ListNode(-1);
Head->next=pHead;
//新建两个指针,start负责定起点,end负责找到重复字符的尾端
ListNode* start=Head;
ListNode* end=start->next;
while(end){
if(end->next and end->val==end->next->val){
//当有重复时,end指针找到最后一个重复字符,start下一个指针指向end的下一位
while(end->next and end->val==end->next->val){
end=end->next;
}
//start指针还在原始位置,指向位置变了
start->next=end->next;
end=end->next;
}
else{
//当没有重复时,start和 end指针都顺势往后一步
start=end;
end=end->next;
}
}
return Head->next;
}
};
17. 正则表达式匹配
这题要考虑的情况太多了,要是不开练习模式不断地试,感觉做不出来。
这还是看了书上的做法才做出来的
class Solution {
public:
bool match(char* str, char* pattern)
{
if(str==nullptr or pattern==nullptr) return false;
return matchbool(str, pattern);
}
private:
bool matchbool(char* str, char* pattern){
if(*str=='\0' and *pattern=='\0') return true;
if(*str!='\0' and *pattern=='\0') return false;
if(*(pattern+1)=='*'){
if(*str== *pattern || (*pattern=='.' and *str!='\0'))
//在返回的值里考虑到各种情况。
return matchbool(str+1, pattern)|| matchbool(str+1, pattern+2)|| matchbool(str, pattern+2);
else
return matchbool(str, pattern+2);
}
if(*str== *pattern || (*pattern=='.' and *str!='\0') )
return matchbool(str+1, pattern+1);
else return false;
}
};
18. 表示数值的字符串
自己写的有点麻烦,感觉在穷举
class Solution {
public:
bool isNumeric(char* string)
{
if(string==nullptr) return false;
int indexflag=0;
int decimalflag=0;
//确保字符开头有数字;
if(*string=='+' || *string=='-'){
if(*(string+1)>='0' && *(string+1)<='9')
string+=2;
else if(*(string+1)>='.'){
string+=2;
decimalflag=1;
}
else return false;
}
else if(*string>='0' && *string<='9')
string+=1;
else return false;
//遇到数字往后一步,直到遇到符号或者字符结尾结束
while (*string!='\0'){
if(*string>='0' && *string<='9'){
string++;
}
//遇到小数点,小数点下一位不是数字就false,小数点在指数后false
else if(*string=='.' && !decimalflag && !indexflag){
if(*(string+1)>='0' && *(string+1)<='9'){
decimalflag=1;
string++;
}
else return false;
}
//遇到指数,指数下一位不是符号或数字就false
else if((*string=='e' || *string=='E')&& !indexflag){
string++;
if((*string=='+' || *string=='-') && (*(string+1)>='0' && *(string+1)<='9'))
{
string+=2;indexflag=1;
}
else if (*string>='0' && *string<='9'){
string+=1;indexflag=1;
}
else return false;
}
else return false;
}
return true;
}
};
别人的思路,简单明了很多,按符号将不可以的情况列举并返回false
class Solution {
public:
bool isNumeric(char* string)
{
if(string==nullptr) return false;
int indexflag=0;
int decimalflag=0;
if(*string=='+' || *string=='-') string+=1;
while (*string!='\0'){
//如果是+-号
if(*string=='+' || *string=='-'){
//后面只能是数字或.
//前面只能是E 或没有
if(*(string-1)!='E' && *(string-1)!='e') return false;
else if(*(string+1)<'0' && *(string+1)>'9' && *(string+1)!='.') return false;
}
//是.号
else if(*string=='.' && !decimalflag && !indexflag){
//不在e后
//不能出现两次
//不能后面没数字
if(*(string+1)<'0' || *(string+1)>'9') return false;
else decimalflag=1;
}
//是e,E
else if((*string=='e' || *string=='E')&& !indexflag){
//不能有两次
//后面不能有小数
//不能后面没有数
if((*(string+1)<'0' || *(string+1)>'9') && *(string+1)!='+' && *(string+1)!='-' && *(string+1)!='.')
return false;
else indexflag=1;
}
//如果不是数字;
else if(*string<'0' || *string>'9') return false;
string++;
}
return true;
}
};
19. 调整数组顺序让奇数位于偶数前面
构建新数组分别储存奇数偶数,再合并回原数组。
class Solution {
public:
void reOrderArray(vector<int> &array) {
int size=array.size();
vector<int> odd(size);
vector<int> even(size);
int oddindex=0;
int evenindex=0;
for(int i=0;i<size;i++){
if(array[i]%2) odd[oddindex++]=array[i];
else even[evenindex++]=array[i];
}
for(int i=0;i<oddindex;i++) array[i]=odd[i];
for(int i=0;i<evenindex;i++) array[oddindex+i]=even[i];
return;
}
};
插入排序的方法
class Solution {
public:
void reOrderArray(vector<int> &array) {
int size=array.size();
int evenindex=-1;
for(int i=0;i<size;i++){
//找到偶数所在的初始位置
if(!(array[i]%2) && evenindex==-1) {
evenindex=i;
}
//将后面的奇数插入到偶数之前,并将evenindex+1
if(evenindex!=-1 && array[i]%2){
int temp=array[i];
int tempindex=i;
while(tempindex-1>=evenindex){
array[tempindex]=array[tempindex-1];
tempindex--;
}
array[evenindex++]=temp;
}
}
return;
}
};
20. 链表中倒数第k个节点
书上的方法,遍历一遍就可找到k节点。
利用两个指针,一个指针到k-1节点的时候,另一个指针开始动。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==NULL) return NULL;
ListNode* Head1=pListHead;
ListNode* Head2=pListHead;
int i=k;//因为k是无符号整数,所以不能直接用它减,会没完没了。
while(--i){
if(Head1->next!=NULL)
Head1=Head1->next;
//链表长度小于k
else return NULL;
}
while(Head1->next!=NULL){
Head2=Head2->next;
Head1=Head1->next;
}
return Head2;
}
};