今天的三道题都还行,其中设计链表的时候调试的比较久,另外两题都刷过。
203.移除链表元素
ListNode* removeElements(ListNode* head, int val) {
//思路:创建一个头结点,然后使用两个指针对链表进行遍历,找到时删除,判断头尾节点情况
//问题:再遍历到尾节点时没有把尾节点置为空指针,导致一直循环超时
ListNode*newHead=new ListNode();
newHead->next=head;
ListNode*pre=newHead,*cur=head;
while(cur!=nullptr)
{
if(cur->val==val)
{
if(cur->next!=nullptr)
{
pre->next=cur->next;
cur->next=nullptr;
cur=pre->next;
}
else//尾节点
{
pre->next=nullptr;
cur=nullptr;
}
continue;
}
pre=cur;
cur=cur->next;
}
return newHead->next;
}
newHead的创建是考虑到需要移除的元素是head时的情况。
二刷:1.新头结点 2.前后指针
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode*newHead=new ListNode();
newHead->next=head;
ListNode*pre=newHead,*cur=head;
while(cur){
if(cur->val==val){
if(cur->next) pre->next=cur->next;
else pre->next=nullptr;
}else pre=cur;
cur=cur->next;
}
return newHead->next;
}
};
707.设计链表
class MyLinkedList {
struct Node{
int val;
Node*next;
Node(int _val)
{
val=_val;
next=nullptr;
}
Node()
{
val=0;
next=nullptr;
}
};
public:
//先设计单链表
//需要一个指针指向头结点,一个指针指向尾节点,一个指针记录下标
//思路:使用哈希表存储,键为节点下标,值为节点,使用一个变量记录节点的个数
//问题:简单问题搞复杂
int count=0;//
Node*head=new Node();
MyLinkedList() {
}
int get(int index) {//获取index下标的节点值
if(index>=count)
return -1;
int mid=0;
Node*p=head->next;
while(p)
{
if(mid==index)
break;
mid++;
p=p->next;
// cout<<p->val<<endl;
}
return p->val;
}
void addAtHead(int val) {//头插法
Node*node=new Node(val);
node->next=head->next;
head->next=node;
count++;
cout<<count<<endl;
}
void addAtTail(int val) {//尾加法
Node*p=head;
Node*node=new Node(val);
while(p)
{
if(p->next==nullptr)
{
p->next=node;
break;
}
p=p->next;
}
count++;
cout<<count;
}
void addAtIndex(int index, int val) {//指定下标插入
if(index>count)
return;
Node*node=new Node(val);
Node*cur=head->next,*pre=head;
int mid=0;
if(count==index)
{
addAtTail(val);
return;
}
while(cur)
{
if(mid==index)
{
node->next=cur;
pre->next=node;
break;
}
pre=cur;
cur=cur->next;
mid++;
}
count++;
}
void deleteAtIndex(int index) {//删除指定下标节点
if(index>=count)
return;
// cout<<count;
Node*cur=head->next,*pre=head;
int mid=0;
while(cur)
{
if(mid==index)
{
pre->next=cur->next;
cur=nullptr;
break;
}
mid++;
pre=cur;
cur=cur->next;
}
count--;
}
};
这一题本来想利用哈希表的查找特性,但是实现过程中越来越复杂,最后采取了暴力查找的方法
二刷:同样的配方
- 两个容易忽略的点:1.添加提前返回时,记得长度自增 2.添加到最后一个时,index==链表长度
class MyLinkedList {
public:
struct ListNode{
int val;
ListNode*next;
ListNode():val(0),next(nullptr){};
ListNode(int _val):val(_val),next(nullptr){};
};
public:
int _size;
ListNode*root=new ListNode();
MyLinkedList() {
_size=0;
}
int get(int index) {
cout<<_size<<endl;
if(index>=_size) return -1;
ListNode*cur=root->next;
while(index--) cur=cur->next;
return cur->val;
}
void addAtHead(int val) {
ListNode*node=new ListNode(val);
node->next=root->next;
root->next=node;
_size++;
}
void addAtTail(int val) {
_size++;
ListNode*node=new ListNode(val);
if(root->next==nullptr){
root->next=node;
return;
}
ListNode*cur=root->next;
while(cur->next) cur=cur->next;
cur->next=node;
}
void addAtIndex(int index, int val) {
if(index>_size) return;
ListNode*node=new ListNode(val);
ListNode*pre=root,*cur=root->next;
while(index--){
pre=cur;
cur=cur->next;
}
node->next=cur;
pre->next=node;
_size++;
}
void deleteAtIndex(int index) {
if(index>=_size) return;
ListNode*pre=root,*cur=root->next;
while(index--){
pre=cur;
cur=cur->next;
}
if(cur && cur->next){
pre->next=cur->next;
cur=nullptr;
}else pre->next=nullptr;
_size--;
}
};
206.反转链表
class Solution {
public:
ListNode* reverseList1(ListNode*node)
{
if(node==nullptr || node->next==nullptr)
return node;
ListNode*newHead=reverseList1(node->next);
node->next->next=node;
node->next=nullptr;
return newHead;
}
ListNode* reverseList(ListNode* head) {
//思路:递归翻转
return reverseList1(head);
}
};
这一题做过多次,比较熟悉