配套力扣剑指offer剑指 Offer。
刷题顺序同上。同时结合书上内容。
目录
1. 剑指 Offer 24. 反转链表
牛客做过。注意一下,要考虑到当前节点head
为空的可能性,要加一句判断。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* tmp;
ListNode* nex=nullptr;
if(head==nullptr || head->next==nullptr) return head;
while(head->next!=nullptr)
{
tmp=head->next;//先保存正序的下一个指针
head->next=nex;//重新给next赋值
nex=head;//更新下一次用于赋值给next的内容
head=tmp;//迭代节点
}
head->next=nex;//给最后节点赋next,变成新的头节点
return head;
}
};
2. 剑指 Offer 35. 复杂链表的复制
一开始考虑直接返回head
,不行。
考虑只拷贝第一个节点,后面节点不变,不行。会检测新的节点是不是原来的节点的拷贝,或者是否指向原来的节点。
只考虑单链表,其实比较简单,除了要先把头节点建立,判断有没有下一节点,没有就给nullptr
,有就先构建nex
,然后把head
给cur
,构建cur
和nex
关系;然后循环判断nex
的下一节点是否为空,不为空就先把nex
给cur
,然后找一下下一节点nex
,再创建指向;最后再把nex
的下一节点给nullptr
就可以。
但是复杂链表的话random
节点不好直接构建连接,因为有的节点可能还没有构建。
要用哈希。学一下。
作者:jyd
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
来源:力扣(LeetCode)
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head == nullptr) return nullptr;//先判空,为空直接输出空指针
Node* cur = head;
unordered_map<Node*, Node*> map;
// 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
while(cur != nullptr) {
map[cur] = new Node(cur->val);//利用map容器实现节点复制,注意这里要用new分配内存,每个原始链表的节点作为key,复制的节点作为value
cur = cur->next;
}
cur = head;
// 4. 构建新链表的 next 和 random 指向
while(cur != nullptr) {
map[cur]->next = map[cur->next];//这里非常精彩,原始链表节点作为key相当于索引,去定位复制节点
map[cur]->random = map[cur->random];
cur = cur->next;
}
// 5. 返回新链表的头节点
return map[head];
}
};
3. 剑指 Offer 05. 替换空格
注意string
的push_back()
只能增加1个字符。
class Solution {
public:
string replaceSpace(string s) {
int size=s.size();
string ss;
for(int i=0;i<size;i++)
{
if(s[i]!=' ') ss.push_back(s[i]);
else
{
ss.push_back('%');
ss.push_back('2');
ss.push_back('0');
}
}
return ss;
}
};
4. 剑指 Offer 58 - II. 左旋转字符串
主要用到string
的assign
函数,注意str.assign(s,index,num);
,把s
从index
开始的num
个字符赋值给str
,然后字符串可以直接相加。
class Solution {
public:
string reverseLeftWords(string s, int n) {
string str;
int k=n%s.size();
if(k==0) return s;
str.assign(s,k,s.size()-k);
string stmp;
stmp.assign(s,0,k);
str+=stmp;
return str;
}
};
5. 剑指 Offer 03. 数组中重复的数字
看到要统计数字个数,而且统计的数字不重复,就想到应用以下unordered_map
,但是其实遍历挺耗时的。
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int,int> memo;
for(auto i:nums)//注意这里就是遍历nums的每一个元素
{
memo[i]++;//一旦有重复数字就个数+1
}
for(int i=0;i<memo.size();i++)
{
if(memo[i]>1) return i;
}
return 0;
}
};