代码训练营第三天

今天刚上来有点疲惫 但是由于是二刷 还是轻松不少

链表:

一个结点是由数据域和指针域组成的 其中指针域存放指项下一个结点的指针 最后的结点指向nuLL

u主要就是c++中链表结点是如何定义的 因为leetcode中都定义好了 所以很多人写不出来 

其实就是

struct listnode{

int val;

listnode *next;

listnode(int x): val(x), next(NULL) {}       //这个构造函数其实是构造一个头结点 所以只用传val就行了 next是指向NULL的(next的默认值为null)

}

这个最后可加分号可不加.

第一题:移除链表元素

还是要注意几个点 

1 就是你定义了struct类的结构体后 不能再用int *p去指向它  因为它已经是listnode 型的指针了 只能说是定义一个listnode *p 类型的指针 去指向。 此外也没有必要去调用构造函数 去创建一个p 因为只能说创建一个指针 而不是创建对象。

2第二个问题是 你如果是定义了指针去指向 那么你就不能用. 而是要用-> 因为.是结构体的东西 而->是相当于是委托 而且是委托到底 去最终去得到这个值

3free是c语言用的 c++用的是delete 而且要注意不管是free还是delete后 这个指针p就无效了 要重新定义。 所以要在循环里定义一个tem变量用于释放。在c++中 `delete`不会只释放指针本身,而是会同时释放指针所指向的对象。

4第四个问题就是 你可以虚拟一个头结点 但是最后一定要注意回收 不然就出问题了。

最终代码如下:

class Solution {

public:

    ListNode* removeElements(ListNode* head, int val) {

        ListNode *head1 =new ListNode ();

        head1->next=head;

        ListNode *p=head,*pre=head1;

        while(p!=NULL){

            if(p->val==val){

                ListNode *tem=p;

                pre->next=p->next;

                p=p->next;

                delete tem;

                

            }

            else{

                p=p->next;

                pre=pre->next;

            }

        } 

        head=head1->next;

        delete head1;

        return head;

    }

};

第二题 

1注意初始化 指得是让你生成头结点 而不是让你定义结构

2注意在初始化的时候 最好要加一个size值 这样方便操作。 在单向链表和双向链表中 都最好去加上一个size值。 这个size就是链表下表 可以看看题目的要求来决定

3另外就是在初始化的时候 只用初始虚拟头结点就可以了 不用定义头结点 因为头结点也就是第一个数据 在插入的时候直接插入就可以了

4还是要注意: 从0开始! 数组下标从0开始!

5 LinkedNode *p  p是定义在栈上的 只有new出来的才是定义在堆上的。

6在创建链表的时候,最好是直接创建成引用或者指针类型 而不是直接定义一个对象 因为这样会速度很快

你就想嘛 你直接操作很多对象 哪有直接操作指向对象的指针快呢

具体原因:在链表的实现中,由于需要频繁对节点进行插入、删除等操作,因此使用指针会比使用对象更加方便,这是因为在使用指针时可以直接通过内存地址进行操作,而在使用对象时需要进行额外的拷贝或者构造,会产生额外的开销。

因此,在链表的实现中,通常会使用节点的指针来表示链表,这样可以方便地进行插入、删除、查找等操作。在具体实现中,可以在节点类中使用智能指针,如shared_ptrunique_ptr,来管理节点的内存,以避免手动管理指针所带来的安全问题。

7还有就是

 struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

这个构造函数的

  LinkedNode(int val):val(val), next(nullptr){}

这一行 不用在next前加指针 因为next本身就是指针变量 只是在定义的时候前面要加* 

8 如果你是用多一个size 那么你要时时刻刻去维护这个size

9如果是有节点下标的题 那么就肯定要用一个size

10就是可以说用一个size去维护  也可以说是用循环编历 相当于说是循环 看是否相等

11要注意size要先定义为int

12c++中写完public 还要写private

13还有要注意在函数中定义的变量 只能在函数的作用域中使用。 不然就必须在private里面再去定义。 这样在整个类中都能使用。 再去使用的时候,不用去再去声明类型 只要用名称就可以了。

另外最好用_下划线 这个成员访问符来访问:成员访问符 " _ "(下划线)在C++中常用于区分成员变量和局部变量或函数参数。因为C++允许在函数内部定义局部变量或参数的名称与成员变量的名称相同,如果没有使用成员访问符来区分,编译器可能会将局部变量或参数当成成员变量使用,导致程序出现错误。

class MyLinkedList { public: struct LinkedNode { int val; LinkedNode* next; LinkedNode(int val):val(val), next(nullptr){} }; MyLinkedList() { head = new LinkedNode (0); size1 = 0; } int get(int index) { if(index >=size1||index<0){ return -1; } LinkedNode* p=head->next; while(index--){ p=p->next; } return p->val; } void addAtHead(int val) { LinkedNode *pre=new LinkedNode (val); LinkedNode *p=head->next; head->next=pre; pre->next=p; size1++; } void addAtTail(int val) { LinkedNode *p=head; LinkedNode *newnode=new LinkedNode (val); while(p->next!=NULL){ p=p->next; } p->next=newnode; newnode->next=NULL; size1++; } void addAtIndex(int index, int val) { if(index>size1||index<0) {return;} if(index==size1){ addAtTail(val); return; } LinkedNode *p=head; while(index--){ p=p->next; } LinkedNode *newcode=new LinkedNode (val); newcode->next=p->next; p->next=newcode; size1++; } void deleteAtIndex(int index) { if(index >=size1||index<0){ return ; } LinkedNode *p=head; while(index--) p=p->next; LinkedNode *tem=p->next; p->next=p->next->next; delete tem; size1--; } private: int size1; LinkedNode* head; }; /** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList* obj = new MyLinkedList(); * int param_1 = obj->get(index); * obj->addAtHead(val); * obj->addAtTail(val); * obj->addAtIndex(index,val); * obj->deleteAtIndex(index); */

我们来看一下第三个题 

1主要是你在反转链表的时候 应该是用p->next去指向pre->next 注意!!

2还有一个点是 也可以直接把指向NULL的指针再去回指 不会出问题 指向NULL也是指针

3还有一个问题是 反转链表其实不用prehead结点 就算你加上 到最后如果链表是NULL的话,那么你去返回的时候就有问题了 不是返回的pre。 所以这样还要单独讨论 所以最好就是不去加头结点 因为你是反转链表 加了反而有问题 不如直接把pre设为NULL就是最好。 这点需要去学习一下 因为直接不管是插入还是什么的 都是在之后去弄 而不是之前去弄 你设计虚拟头结点如果是之前去弄的话就反而更麻烦了。

具体代码如下 还是很简单的  就是一些细节要注意:

class Solution {

public:

    ListNode* reverseList(ListNode* head) {

        ListNode* p=head;

        ListNode* pre=NULL;

        

        while(p!=NULL){

            ListNode* tem=p->next;

            p->next=pre;

            pre=p;

            p=tem;

        }

        return pre;

    }

};

因为第二题掌握的不好所以再去重做一下:

1 如果题目没有去struct定义 那么你就要自己定义了 在函数之前。

2注意struct要用分号结尾! 因为c++中struct和类一样都要用分号结尾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。
第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值