剑指offer
左旋转字符串
题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
解题思路:
解法1:使用标准库
string::substr(size_type __pos, size_type __n)
;string::substr(pos, n)
表示截取字符串string,从pos下标开始,长度为n的子串。
比如:str = "helloworld",
那么str.substr(2,3)
等于"llo"
解法2:遍历数组,利用辅助字符串
解法3:后面补上相同的字符串str;
class Solution {
public:
string LeftRotateString(string str, int n) {
/* if(n>str.size()) return str;
string ret="";
for(int i=n;i<str.size();i++){
ret+=str[i];
}
for(int i=0;i<n;i++){
ret+=str[i];
}
return ret;*/
//return n>str.size()?str:str.substr(n,str.size()-n)+str.substr(0,n);
//*str+str;
int len=str.length();
if(len==0) return "";
str=str+str;
return str.substr(n,len);
}
};
反转单词序列
题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
解题思路
解法1:先翻转整个字符串,再反转单词;注意空格
解法2:使用stringstream库函数
解法3:从后往后遍历,部分截取最后加上空格;
//使用stringstream函数,时间复杂度O(n),空间复杂度O(n);
class Solution {
public:
string ReverseSentence(string str) {
// 预处理
if (str.empty()) return str;
int i = 0, sz = str.size();
while(i < sz && str[i] == ' ') ++i;
if (i == sz) return str;
istringstream ss(str);
vector<string> ret;
string s;
// 拆分单词
while (ss >> s)
ret.push_back(s);
reverse(ret.begin(), ret.end());
ostringstream oss;
// 合并成字符串
for (int i=0; i<ret.size()-1; ++i)
oss << ret[i] << ' ';
oss << ret.back();
return oss.str();
}
};
//解法3:时间复杂度为O(n),空间复杂度O(n);
class Solution {
public:
string ReverseSentence(string str) {
if(str.empty()) return "";
int cnt=0,sz=str.size();
while(cnt<sz&&str[cnt]==' ') cnt++;
if(cnt==sz) return str;
string res="";
int right=str.size()-1;
int left=right;
while(left>=0){
while(left>=0&&str[left]==' '){
left--;
right=left;
}
while(left>=0&&str[left]!=' '){
left--;
}
if(left!=right){
res+=str.substr(left+1,right-left)+" ";
}
}
//除去最后的空格
if(!res.empty()){
res.pop_back();
}
return res;
}
};
1+2+3+…+n
题目描述
解题思路:
利用短路原理:
a&&b
,a为0,不会执行b,a||b
;a为1不会执行b
代码实现
class Solution {
public:
int Sum_Solution(int n) {
int sum=n;;
sum&&(sum+=Sum_Solution(n-1));
return sum;
}
};
不用加减乘除法做加法
题目描述:
解题思路:
class Solution {
public:
int Add(int num1, int num2)
{
int result=0;
int carry=0;
do{
result=num1^num2;//不带进位的加法
carry=(num1&num2)<<1;//进位
num1=result;
num2=carry;
}while(carry!=0);//进位不为0则继续执行加法处理进位;
return result;
}
};
把字符串转换成整数
解题思路
先判断第一位是正号还是负号;然后利用isdigit()判断是否是数字。
对于“123456”可以利用如下代码进行转化
int ans = 0;
for (int i=0; i<str.size(); ++i) {
ans = ans * 10 + (str[i] - '0');
}
代码实现:
class Solution {
public:
int StrToInt(string str) {
int flag=1,i=0;
long res=0;
if(str[i]=='-') flag=-1;
if(str[i]=='+'||str[i]=='-') i++;
for(;i<str.size();i++){
if(!isdigit(str[i])) return 0;
res=res*10+(str[i]-'0');
}
return flag*res;
}
};
删除链表中重复的节点
题目描述
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
//设置虚拟头节点,
ListNode *vhead=new ListNode(-1);
vhead->next=pHead;
//cur用于遍历链表,pre用于指向没有重复的链表
ListNode *cur=pHead;
ListNode *pre=vhead;
while(cur){
if(cur->next&&cur->val==cur->next->val){
cur=cur->next;
//找到最后一个相同的节点
while(cur->next&&cur->val==cur->next->val){
cur=cur->next;
}
//最后一个相同的节点向后移动一位
cur=cur->next;
pre->next=cur;
}else{
pre=cur;
cur=cur->next;
}
}
return vhead->next;
}
};
二叉树的下一个结点
题目描述:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
代码实现:
/*
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:
//树的中序遍历
void min_order(TreeLinkNode *root,queue<TreeLinkNode*>&que){
if(!root){
return ;
}
min_order(root->left,que);
que.push(root);
min_order(root->right,que);
}
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==nullptr) return nullptr;
TreeLinkNode *root=pNode;
while(root->next){
root=root->next;
}
queue<TreeLinkNode *>que;
min_order(root,que);
while(que.front()!=pNode){
que.pop();
}
que.pop();
if(que.empty()) return nullptr;
return que.front();
}
};