2024.03.04——2024.03.10 力扣练习总结及专项巩固

1. (18. 四数之和)已知在一个cpp程序中,使用了"#include<algorithm>"语句,声明引入algorithm头文件。现在假如有一个vector<int>类型的变量nums={-1, 3, 1, -2},如果仅使用一个语句对其进行排序,使得nums=[-2, -1, 1, 3],则该语句是:

A. nums.sort();

B. sort(nums);

C. sort(nums.begin(), nums.end());

D. sort(nums.end(), nums.begin());

2. (18.四数之和)在四数之和的官方题解中,有一种解法的思路是:先进行双重循环,分别确定下来第一个数和第二个数的位置。在确定了第一个数和第二个数的位置之后,再使用双指针。在某一次进行双重循环的第二层循环时,记第一个数的索引为first,第二个数的索引为second,数组nums长度为len,目标值为target。如果nums[first]+nums[second]+nums[len-2]+nums[len-1] < target,那么此时应该做的操作是:

A. break;

B. continue;

3. (18.四数之和)同第2问,在某一次进行双重循环的第二层循环时,记第一个数的索引为first,第二个数的索引为second,数组nums长度为len,目标值为target。如果此时nums[first]+nums[second]+nums[second+1]+nums[second+2] > target,那么此时应该做的操作是:

A. break;

B. continue;

4. (18. 四数之和)在四数之和的官方题解中,有一种解法的思路是:先进行双重循环,分别确定下来第一个数和第二个数的位置。在确定了第一个数和第二个数的位置之后,再使用双指针进行处理。而无论是进行双重循环,抑或是后面使用双指针进行处理,都需要判断是否重复。在双重循环的第一次循环过程中,判断第一个数是否重复时,假如第一个数的索引为first,且first的初值为0,则下面两个判断是否重复的语句效果相同嘛?为什么?

if(first > 0 && nums[first] == nums[first-1])

if(nums[first] == nums[first+1])

5. (18. 四数之和)同第4问,在双重循环的第二次循环过程中,判断第二个数是否重复时,假如第二个数的索引为second,且second的初值为0,则下面两个判断是否重复的语句效果相同嘛?为什么?

if(second > first+1 && nums[second] == nums[second-1])

if(nums[second] == nums[second+1])

6. (18. 四数之和)在leetcode界面中编写函数代码时,函数代码被放到了一个类里面,这对初学者的理解造成了很大的困难。然而当我们学过C++中的类之后,便明白了leetcode中的类其实就是一个塑料袋,很轻很薄而且只有一个简陋的包装作用,把函数装在里面而已。那么当我们在编写这道题目的函数时,有两个参数,分别是int型的vector容器变量nums,以及int型的变量target。在传递参数时,第二个参数所需的空间很小很小,并不需要担心。对于第一个参数nums,虽然其在题目示例中给出的大小很小,但在实际运行过程中却有时候会很大,这时候为了减少空间开销,我们选择将变量的引用传递过去,其调用代码为:

A. vector<vector<int>> fourSum(vector<int>* nums, int target){...

B. vector<vector<int>> fourSum(vector<int> nums, int target){...

C. vector<vector<int>> fourSum(vector<int>& nums, int target){...

7. (18. 四数之和)在四数之和的官方题解中,用到的方法是双重循环加双指针,其中双指针仍需要一个while循环,遍历在第一、二个数确定之后第三、四个数的情况。则一共需要的循环重数是:

A. 2,只有两个for循环

B. 3,两个for循环和一个while循环

C. 4,两个for循环和两个while循环,分别遍历四个数

8. (18. 四数之和)在用双指针进行处理时,如果四个数的和sum等于target,那么需要保存下来此时的四个数,记答案被保存在vector<vector<int>>类型的变量ans中,四个数取自数组nums,则保存此时的四个数的代码是:

A. ans.push_back({nums[first], nums[second], nums[third], nums[fourth]});

B. ans.push_back(nums[first], nums[second], nums[third], nums[fourth]);

C. ans.push_back(first, second, third, fourth);

D. ans.push_back([nums[first], nums[second], nums[third], nums[fourth]]);

8. (18. 四数之和)已知双指针进行处理的过程可分为三种情况:第一种,四个数的和sum等于target;第二种,四个数的和sum大于target;第三种,四个数的和sum小于target。毫无疑问,对于第二种情况,既然四个数的和大了,那就左移第四个数的索引fourth即可;对于第三种情况,既然四个数的和小了,那就_________即可。真正棘手的是第一种情况。此时的操作应为:

(1)保存下来此时的四个数;

(2)__________________;

(3)左移第四个数的索引fourth;

在这里要同时移动两个索引third与fourth。为什么要同时移动两个索引,而不是只移动一个呢?_______________。接着无论是进行双重循环,抑或是后面使用双指针进行处理,都需要判断是否重复。那么在使用双指针进行处理时如何判重呢?____________________。

9. (18. 四数之和)整理一下,四数之和的解题思路即为:双重循环+____。但是在此之前,对于传递过来的数组nums,还需要进行______处理,以保证后续操作能正常进行。在进行双重循环时,第一重循环处理第一个数的索引first,需要使用三个if,分别完成________,何时break,何时continue这三个任务,第二重循环处理第二个数的索引second,同样需要使用三个if,分别完成________,_______,_________这三个任务。在进行双指针处理时,根据四个数的和sum与target的大小关系,需要分为____种情况进行讨论。比较简单的是________以及_______这两种情况,而复杂的是sum == target这种情况。当sum == target时,除了需要保存此时的四个数,同时还需要同时移动两个指针,以及进行判重操作。如何进行判重操作呢?______________。

10. (18. 四数之和)如果我们只是在leetcode上做题,那么只需要提交函数代码,不需要自己编写main函数,构造测试用例来检验函数代码的正确性。而如果我们想在自己的电脑上,编写一个完整的C++程序,那么我们就需要再编写一个main函数。而为了输出vector<vector<int>>型的变量ans的值,我们需要使用迭代器,请完成下面的代码:

Solution Solution1;
vector<vector<int>> ans = Solution1.fourSum(nums, target);
vector<vector<int>>::iterator iter = ans.begin();
for(; iter____ans.end(); iter++){
    vector<int>::iterator sub_iter = (*iter).begin();
    for(; sub_iter____(*iter).end(); sub_iter++){
        cout <<____<< ' ';
    }
    cout << endl;
}

11. (19. 删除链表的倒数第N个结点)对于这道题,有三种解法,第一种是最简单的解法,即先遍历一遍获取链表长度,接着再遍历第二遍,只不过第二遍没有走到头,而是走到了规定地方就停止;第二种解法是使用栈,第三种解法是使用快慢指针。对于第一种解法,首先要获取链表的长度,试填写以下两种不同形式的函数getLength的代码段:

int getLength(ListNode* head){
    int count = 1;
    while(____) {head = head->next; count++;}
    return count;
}
int getLength(ListNode* head){
    int count = 0;
    while(____) {head = head->next; count++;}
    return count;
}

12. (19. 删除链表的倒数第N个结点)同11题,对于第一种解法,首先要获取链表的长度,在获取到链表的长度之后,接着就要编写函数移除指定位置的结点。当链表的长度比较长时,比如为3->2->1->0, n = 2,问题很简单,可以

ListNode* cur = head;
while(int i = 1; i__getLength(head) - n; i++) { cur = cur->next; }
ListNode* tmp = cur->next;
cur->next = tmp->next;
delete(tmp);
return head;

。而如果链表的长度比较短,比如为1, n = 1,这时如果将这种情况单独提出来,与一般情况分开对待,不失为一种好方法。而如果想将所有情况混合在一起,就会发现比较棘手,报错会出现在( )

A. while(int i = 1; i__getLength(head) - n; i++) { cur = cur->next; }

B. ListNode* tmp = cur->next;

C. cur->next = tmp->next;

D. delete(tmp);

13. (19. 删除链表的倒数第N个结点)接12题的情况,为了解决这个棘手的问题,选择引入一个哑结点dummy(0, head),修改之后的代码为:

ListNode* removeNthFromEnd(ListNode* head, int n) {
    int len = getLength(head);
    ListNode* dummy = new ListNode(0, head);
    ListNode* cur = dummy;
    for(int i = 0; i___len-n; i++) cur = cur->next;
    ListNode* tmp = cur->next; cur->next = ___->next; delete ___;
    head = dummy->next; delete dummy;
    return head;
}

14. (19. 删除链表的倒数第N个结点)接13题的情况,这个时候有一种答案,思路跟13题的思路相同,但程序却报错了,这启示我们凡是涉及到求长度的问题时,都尽量设一个变量来保存它,即"int len = getLength(head);"是有必要的,请指出下面代码段的问题:

ListNode* dummy = new ListNode(0, head);
head = dummy;
for(int i = 0; i < getLength(head)-n; i++) head = head->next;
ListNode* tmp = head->next; head->next = tmp->next; delete tmp;
head = dummy->next; delete dummy;
return head;

15. (19. 删除链表的倒数第N个结点)整理求解此题的第一种解法的思路:首先计算出链表的长度,可以通过一个while循环来完成,当循环条件是head != NULL时,count的初值为___;当循环条件是head->next != NULL时,count的初值为___。接着编写删除结点的函数。为了编写通用于getLength(head) == 1以及getLength(head) > 1两种情况的代码,我们选择引入哑结点,这行代码是ListNode* dummy = ___ ListNode(0, ___); 引入哑结点。另外为了避免出错,我们最好提前保存下来链表的长度,即int len = getLength(head)。最终除了要删除倒数第N个结点之外,还应该删除____。

16. (19. 删除链表的倒数第N个结点)对于这道题的第二种解法,即采用栈作为辅助结构,是怎么具体实现的呢?它先让链表依次入栈,入完栈之后,再依次出栈,将倒数N-1个结点都出栈之后,记录下接下来要出栈的结点为prev,即ListNode* prev = stk.pop(),然后prev->next = _________; 在这里,一般的栈再弹出结点时,弹出的一个结点如果不被保存,那就是真的再也找不到了,而在这道题中,弹出栈的结点____(能\不能)被找到,因为栈中的结点是被用______连接的。所以____(有\没有)必要保存下来原链表中的倒数第N个结点。

17. (19. 删除链表的倒数第N个结点)整理一下这道题的第二种解法的思路:首先引入一个哑结点dummy,具体是LinkNode* dummy = new LinkNode(0, ____); 接着创建一个LinkNode*型的stack容器变量stk,将链表入到这个栈里面去。接着依次出栈,直到下一个即将出栈的结点是原链表中的倒数第____个结点。最终删除倒数第N个结点和______结点。

18. (19. 删除链表的倒数第N个结点)对于这道题的第三种解法,使用快慢指针。当我们搞清楚前两种解法之后,编写第三种解法的代码时所需要的时间和精力就会大大减少。整理一下第三种解法的思路:首先引入一个哑结点dummy,具体代码是_________________________; 接着引入快指针fast和慢指针slow,先让快指针fast和慢指针slow拉开n个距离,接着让快指针fast和慢指针slow同时沿着链移动,直到_________(快指针fast为空\快指针fast的指针域为空),这时慢指针slow指向倒数第N个结点。最终删除_______________。

19. (20. 有效的括号)对于括号匹配问题,常见的解法就是使用栈作为辅助结构。在正式解题之前,先引入一些关于stack类和unordered_map类的内置函数的操作:假设有一个char类型的stack类的变量stk,stack<char> stk; 此时使用stk._____(),如果栈为空,则返回值为true,如果栈不为空,则返回值为false;使用stk._____() 可以弹出栈顶元素,并将这个弹出的元素返回;假如有一个char类型的变量c,char c = 'a'; 使用stk.____(c) 可以将变量c入栈,返回值为是否入栈成功;使用stk.____() 可以返回栈顶元素,而不必将其弹出。假设有一个unordered_map类型的容器变量pairs,其key的类型为char,value的类型也为char。现在有一个char类型的变量d,如果把变量d看成key,想要返回key在pairs中对应的value,则 pairs[ ____ ] 可以实现这个功能;如果把变量d看成key,想知道key在pairs中有没有对应的value,则pairs[ _____ ] 可以实现这个功能。

20. (20. 有效的括号)接19题,开始正式解题。首先要创建一个unordered_map<char, char>类型的变量pairs,其中有三个键值对,分别保存小括号对,中括号对,大括号对。在这里,我们选择将左括号作为value,将右括号作为key,这样子当遇到一个字符c是左括号时,通过pairs.____(c) 发现其不在pairs中,所以stk.____(c)直接入栈;当遇到一个字符c是右括号时,通过pairs.____(c)发现其在pairs中,那么直接将栈顶元素stk.___()与pairs[c]作比较,如果相同那么就匹配,不同就直接返回false。而如果将左括号作为key,右括号作为value的话,类似的可以通过pairs.count(c)来确定左括号入栈,而如果遇到一个字符c是右括号时,这时就只好使用一个循环来遍历pairs,相对于上一种方案,更显复杂,所以将左括号作为______,将右括号作为________。

21. (20. 有效的括号)接20题,接着当开始处理字符串的时候,使用for循环遍历string s。for(char ch: ___ ) { 这时的ch可被分为两种情况:ch为左括号,与ch为______。当ch为左括号时,直接入栈即可;当ch为右括号时,如果栈不空且_________时,弹栈即可,除此之外要么栈空要么不匹配,都要返回false。最终当遍历到字符串的末尾时,如果栈空则返回true,如果栈不空则返回false。通过这样的方式,就可以实现括号匹配。

22. (20. 有效的括号)接21题,复盘汇总括号匹配问题中使用到的三个头文件,分别是_______, _______以及_________,使用了两个容器,分别是_________以及__________,其中unordered_map的key与value均为______类型,并且为了操作方便,最好用key来保存_____(左括号\右括号),用value来保存_____(左括号\右括号)。返回true只有一种情况,那就是当遍历完字符串之后,如果栈_______,则返回true。返回false有三种情况,分别是:当读取到的字符ch为右括号并且栈为空;当读取到字符ch为右括号并且栈不为空,但是_______;当遍历完字符串之后,栈__________。另外还有一种特殊情况,就是如果读取的字符串的长度为____(奇数\偶数),那么此时一定不匹配,也要返回false。

23. (21. 合并两个有序链表)合并两个有序链表的解法一般有两种,第一种是递归,第二种是设置一个哨兵结点使用循环。我们看第一种解法也就是递归。在这里递归使用了四个if条件判断。首先对于给定的两个链的结点list1和list2,如果list1已经到了头,而list2不为空,那么返回list2,也就是直接将list2拼接在排好的链的后面即可,即if(!list1) return ____;接着如果list2已经到了头,而list1不为空,那么返回list1,也就是直接将list1拼接在排好的链的后面即可,即if(!list2) return ____; 再接着,如果list1和list2此时都不为空,但是list1-val却小于list2->val,此时因为已经确定了list1就是值较小的那个结点,所以最后一步返回list1即可。而在最后一步返回list1之前,应有list1->next = mergetTwoLists(________, list2); 最后如果list1-val大于等于list2->val,应有list2->next = mergeTwoLists(______, ______); return list2;

24. (21. 合并两个有序链表)合并两个有序链表的第二种解法,设置一个哨兵结点并使用循环。具体如何操作呢?首先创立一个值任意的哨兵结点preHead,并设置一个指针prev指向它。接着使用循环while(list1 && list2) 如果list1->val更小,那么prev->next = list1; 然后list1与prev都后移;如果list2->val更小,那么___________; 然后list2与_____都后移。最终退出while循环,如果此时list1不为空,则prev->next直接指向list1即可;如果此时list2不为空,则prev->next直接指向____即可。请分析下面这段代码的错误:

ListNode* preHead = new ListNode(-1);
        ListNode* prev = preHead;
        while(list1 && list2){
            if(list1->val <= list2->val){
                prev->next = list1;
                list1 = list1->next;
            }else{
                prev->next = list2;
                list2 = list2->next;
            }
        }
        if(list1 && !list2){
            prev->next = list1;
        }else if(!list1 && list2){
            prev->next = list2;
        }
        ListNode* ans = preHead->next; delete preHead; return ans;

相关推荐

  1. 2024.03.04——2024.03.10 练习总结专项巩固

    2024-03-10 09:38:01       38 阅读
  2. 练习 3.27

    2024-03-10 09:38:01       40 阅读
  3. 练习3.28

    2024-03-10 09:38:01       39 阅读
  4. 练习4.9

    2024-03-10 09:38:01       25 阅读
  5. 练习4.11

    2024-03-10 09:38:01       41 阅读
  6. 练习4.26

    2024-03-10 09:38:01       23 阅读
  7. 练习4.29

    2024-03-10 09:38:01       27 阅读
  8. 练习题

    2024-03-10 09:38:01       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-10 09:38:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-10 09:38:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-10 09:38:01       82 阅读
  4. Python语言-面向对象

    2024-03-10 09:38:01       91 阅读

热门阅读

  1. 自动备份数据到异地服务器(另一台电脑)

    2024-03-10 09:38:01       41 阅读
  2. linux系统elk组件logstash部署

    2024-03-10 09:38:01       36 阅读
  3. 旅游专业VR虚拟仿真情景教学实训

    2024-03-10 09:38:01       41 阅读
  4. 排序之冒泡排序

    2024-03-10 09:38:01       44 阅读
  5. ABC344 A-E题解

    2024-03-10 09:38:01       46 阅读