目录
1.剑指Offer
面试题:把字符串转换成整数
题目描述:
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入
+2147483647
1a33
输出
2147483647
0
思路:考虑特殊输入(有非数字字符、正负号、最大正整数最小负整数溢出)、错误处理
代码:
class Solution {
public:
int StrToInt(string str) {
int len=str.length();
if(len==0) return 0;
long long res=0;
int i=(str[0]=='+'||str[0]=='-')?1:0;
for(;i<len;i++){
if(!(str[i]>='0'&&str[i]<='9')){
return 0;
}
res=res*10+str[i]-'0';
}
return str[0]=='-'?(-res):res;
}
};
解析:strlen(str)和str.length()和str.size()都可以求字符串长度,返回字符串中字符的长度,不包括‘/0’。
面试题:链表中倒数第k个节点
题目描述:输入一个链表,输出该链表中倒数第k个结点。
思路:考虑代码的鲁棒性
代码:
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr||k==0){
return nullptr;
}
ListNode* pListAhead=pListHead;
ListNode* pListBehind=pListHead;
for(int i=0;i<k-1;i++){
if(pListAhead->next!=nullptr){
pListAhead=pListAhead->next;
}
else{
return nullptr;
}
}
while(pListAhead->next!=nullptr){
pListAhead=pListAhead->next;
pListBehind=pListBehind->next;
}
return pListBehind;
}
};
https://blog.youkuaiyun.com/thefutureisour/article/details/8147277
举一反三:求链表的中间节点
题目描述:
给定一个带有头结点 head
的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
思路:快慢指针
代码:
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* slow=head;
ListNode* fast=head;
while(fast!=NULL&&fast->next!=NULL){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
};
复杂度分析:
时间复杂度:O(N)O(N),其中 NN 是给定列表的结点数目
空间复杂度:O(1)O(1),slow
和 fast
用去的空间。
2.Leetcode
例1:所有单词拼接的子串索引
题目描述:
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]
You should return the indices:[0,9].
(order does not matter).
代码:
class Solution {
public:
vector<int> findSubstring(string S, vector<string> &L) {
int len=S.length();
int n=L.size();
vector<int> res;
if(len==0||n==0) return res;
int sublen=L[0].size();
int templen=n*sublen;
if(len<templen) return res;
for(int i=0;i<=len-templen;i++){
map<string,int> index;
bool flag=true;
for(int j=0;j<n;j++){
index[S.substr(i+j*sublen,sublen)]++;
}
for(auto t:L){
if(index.find(t)==index.end()){
flag=false;
break;
}
else{
if(index[t]==0){
flag=false;
break;
}
else{
index[t]--;
}
}
}
if(flag){
res.push_back(i);
}
}
return res;
}
};
例2:实现strStr()函数
题目描述:
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
代码:
class Solution {
public:
char *strStr(char *haystack, char *needle) {
int m=strlen(haystack);
int n=strlen(needle);
if(n>m) return nullptr;
int d=m-n;
for(int i=0;i<=d;i++){
int j=0;
for(;j<n;j++){
if(haystack[i+j]!=needle[j]){
break;
}
}
if(j==n){
return haystack+i;
}
}
return nullptr;
}
};
解析:
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。