文章内容为LeetCode刷题笔记,如发现错误请多多指教
26、回文字符串:hash思想
给定一个仅由小写字母组成的字符串。现在请找出一个位置,删掉那个字母之后,字符串变成回文。请放心总会有一 个合法的解。如果给定的字符串已经是一个回文串,那么输出-1。
我们可以从头部和尾部进行字符比较,因为如果是回文字符串的话,头尾是相同的,如果遇到不同的,我们要找的值不是头指针指向的这个值就是尾指针指向的值,只需要在验证下就可以了
#include<iostream>
#include<string>
using namespace std;
bool isPalindrome(string &s,int *start,int *end){
int i=0;
int j=s.size()-1;
bool result = true;
while(i<=j){
if(s[i]==s[j]){
j--;i++;
}
else{
result=false;
break;
}
}
if(start!=nullptr) *start=i;
if(end!=nullptr) *end=j;
return result;
}
int main(){
int num=0;
cin>>num;
while(num){
string s;
cin>>s;
int start =0;
int end=s.size()-1;
if(isPalindrome(s, &start, &end)){
cout<<-1<<endl;
}
else{
//erase(pos,n); 删除从pos开始的n个字符,比如erase(end,1)就是从end开始删除第一个字符(即end)
s.erase(end, 1);
if(isPalindrome(s, nullptr, nullptr)){
cout<<end<<endl;
}
else{
cout<<start<<endl;
}
}
num--;
}
}
27、把数组排成最小的数:排序算法的特殊理解
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中小的一个。例如输入数 组{3,32,321},则打印出这三个数字能排成的小数字为321323。
我们把说法换一下,对于本题,我们要的有效序列是:序列中任何一个元素y,和它前的任何一个元素x进行有序组合形成 xy,比和他后面的任何一个元素z进行有效序列组合yz,满足条件xy < yz(采用字典序列排序) ,如{32,31},有效组合是3132,所以我们拍完序列之后序列变成{31, 32}
class Solution {
public:
static bool cmp(int x,int y){
//要保证找到x,y构成的序列中,让小的放在前面
string nx=to_string(x);
string ny=to_string(y);
string A=nx+ny;
string B=ny+nx;
return A<B;
}
string minNumber(vector<int>& nums) {
if(nums.size()==0){
return " ";
}
//这个排序会根据我们写的cmp方法进行排序,即按小序列升序
sort(nums.begin(),nums.end(), cmp);
string result;
for(int i=0;i<nums.size();i++){
result+=to_string(nums[i]);
}
return result;
}
};
28、两个链表的第一个公共节点:单链表理解,临界条件判定
输入两个链表,找出它们的第一个公共节点。
如下面的两个链表:
在节点 c1 开始相交。
针对这个题,我们可以进行以下思路:
1、首先判断两个链表是否相交,怎么样才算相交呢,必须最后一个节点是相同的才可以,因为相交的话最后一个节点一定是相同的
2、如果相交,怎么找出相交节点呢,那么需要遍历两个链表的节点,并进行节点比较,第一个相同的节点就是我们要找的
3、但是链表长度不一样,比较的话要怎么办呢,我们可以先让长的链表指针走几步,然后再开始一起比较
整理好思路,代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//该方法用来返回链表最后一个节点指针,并且length是一个输出型参数
ListNode *getlistLength(ListNode *head,int &length){
if(head==nullptr){
return head;
}
ListNode *end=head;
while(head){
end=head;
head=head->next;
length++;
}
return end;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//当两个头指针有一个为空的时候,就可以不跟它玩了
if(headA==nullptr||headB==nullptr){
return nullptr;
}
int lengthA=0,lengthB=0;
ListNode *endA=getlistLength(headA,lengthA);
ListNode *endB=getlistLength(headB,lengthB);
//先判断最后节点是否相同,因为如果相交的话,最后一个节点一定是一样的
if(endA!=endB){
return nullptr;
}
//判断两个链表长度,长的一个先走长度差步,然后在一起比对每个节点是否相同
if(lengthA>lengthB){
int step=lengthA-lengthB;
while(step){
headA=headA->next;
step--;
}
while(lengthB){
//如果遍历到相同的节点了,那么直接返回该节点即可,两个节点任选其一返回
if(headA==headB){
return headA;
//break;
}
//如果不相同,那么继续往后走
else{
headA=headA->next;
headB=headB->next;
}
}
}
else{
int step=lengthB-lengthA;
while(step){
headB=headB->next;
step--;
}
while(lengthA){
if(headB==headA){
return headB;
//break;
}
else{
headA=headA->next;
headB=headB->next;
}
}
}
//到达这里说明没有节点是相同的,返回空指针
return nullptr;
}
};