力扣刷题记录(一)剑指Offer(第二版)

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程;

2、个人经历: 研究生期间课题是SLAM在无人机上的应用,有接触SLAM、Linux、ROS、C/C++、DJI OSDK等;
3、参加工作后(2021-2023年)岗位是嵌入式软件开发,主要是服务器开发,Linux、C/C++、网络编程、docker容器、CMake、makefile、Shell脚本、JSON等。

4、求职岗位是嵌入式软件开发、C/C++开发、自动驾驶岗位开发等。

力扣刷题记录(一)剑指Offer(第二版)_第1张图片

本系列记录力扣刷题过程,本文是第一次,剑指Offer(第二版)的记录。

我并没有按照题目的顺序刷,而是按照题的类型刷的,比如从链表开始做,接下来是数组,排序等等。

!!!标记的代表第一次没作对的,需要日后重点反复做几遍的。

文章目录

  • 一、链表部分
    • 1.1 剑指 Offer 06. 从尾到头打印链表
    • 1.2 剑指 Offer 18. 删除链表的节点
    • 1.3 剑指 Offer 22. 链表中倒数第k个节点
    • (!!!)1.4 剑指 Offer 24. 反转链表
    • (!!!)1.5 剑指 Offer 25. 合并两个排序的链表
    • (!!!)1.6 剑指 Offer 52. 两个链表的第一个公共节点
  • 二、数组部分
    • 做数组部分简单题的心得(必看,必看,必看)
    • 2.1 剑指 Offer 03. 数组中重复的数字
    • 2.2 剑指 Offer 11. 旋转数组的最小数字
    • 1.3 剑指 Offer 17. 打印从1到最大的n位数
    • 1.4 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
    • (********不会做)1.5 剑指 Offer 29. 顺时针打印矩阵
    • 1.6 剑指 Offer 39. 数组中出现次数超过一半的数字
    • 1.7 剑指 Offer 40. 最小的k个数
    • (!!!!!!!!!!!!!!!!)2.8 剑指 Offer 42. 连续子数组的最大和
    • 2.9 剑指 Offer 53 - II. 0~n-1中缺失的数字
    • (!!!!!!)2.10 剑指 Offer 57. 和为s的两个数字
    • (!!!!!)2.11 面试题61. 扑克牌中的顺子
  • 三、其他的简单题
    • 3.1(!!!!!) 剑指 Offer 05. 替换空格
    • 3.2(!!!!)剑指 Offer 10- I. 斐波那契数列
    • 3.3 (!!!!) 剑指 Offer 10- II. 青蛙跳台阶问题
    • 3.4 (!!) 剑指 Offer 15. 二进制中1的个数
    • 3.5 (!!)剑指 Offer 50. 第一个只出现一次的字符
    • 3.6(!!!!)剑指 Offer 57 - II. 和为s的连续正数序列
    • 3.7
    • 3.8 剑指 Offer 58 - II. 左旋转字符串

一、链表部分

1.1 剑指 Offer 06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000

我的解答:

C++:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
   
public:
    vector<int> reversePrint(ListNode* head) {
   
		vector<int> vecResult;
		vecResult.clear();

		ListNode *tmp = head;
		while( NULL != tmp)
		{
   
			vecResult.insert(vecResult.begin(),tmp->val);
			tmp = tmp -> next;
		}
		return vecResult;
    }
};

1.2 剑指 Offer 18. 删除链表的节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

注意:此题对比原题有改动

示例 1:

输入: head = [4,5,1,9], val = 5 输出: [4,1,9] 解释: 给定你链表中值为 5
的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2:

输入: head = [4,5,1,9], val = 1 输出: [4,5,9] 解释: 给定你链表中值为 1
的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

说明:

题目保证链表中节点的值互不相同 若使用 C 或 C++ 语言,你不需要 free 或 delete 被删除的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
   
public:
    ListNode* deleteNode(ListNode* head, int val) {
   
		int pos = 1;//用于要删除的是第几个节点
		ListNode *tmp1 = head;//用于指向被删除的节点
		ListNode *tmp2 = head;//用于指向被删除节点的前一个节点
		while(NULL != tmp1 )
		{
   
			cout << "pos is " << pos << endl;
            cout << "tmp -> value is " << tmp1 -> val << endl;
			if(val == tmp1 -> val)//用于指向被删除节点的前一个节点
			{
   
				if(1 == pos)//如果是第一个节点
                {
   
                    head = tmp1 -> next;//需要将头指针指向后一个节点,因为第一个要被删除
                }
				else//如果被删除的不是头结点
                {
   
                   tmp2 -> next = tmp1 -> next;//被删除节点的前一个节点的Next指向被删除节点的后一个节点
				   tmp1 -> next = NULL;//被删除的节点的Next指向空
				   delete tmp1;//释放掉要被删除的节点
                }					
				return head;
				
			}
			else//如果不是要删除的数据,则记录继续往下遍历
			{
   
				tmp2 = tmp1;//此处:tmp2记录下tmp1的前一个节点
				tmp1 = tmp1 -> next;//tmp1继续往下
				pos ++;//记录被删除的是第几个节点
			}
		}
		return head;
    }
};

1.3 剑指 Offer 22. 链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

我的代码:

C语言

struct ListNode* getKthFromEnd(struct ListNode* head, int k){
   

	int i = 0;
	struct ListNode *tmp = head;
	while(NULL != tmp)//while循环的目的是获取链表总节点个数
	{
   
		i++;
		tmp = tmp -> next;
	}
    printf("i is %d",i);
	if(k <= i)
	{
   
		struct ListNode *tmp2 = head;
		int j;
		for(j=1; j != (i - k +1); j++)//for循环的目的是让tmp2指向倒数第k个节点
		{
   
			tmp2 = tmp2->next;
		}//经过for循环后,tmp2已经指向了倒数第k个节点
		if(NULL != tmp2)
		{
   
			struct ListNode *New_head = tmp2;//建立一个新链表,头指针指向tmp2
			return New_head;
		}		
	}
	
	return head;
}

(!!!)1.4 剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

我的代码:

class Solution {
   
public:
    ListNode* reverseList(ListNode* head) {
   
        ListNode *head_new = NULL;//新链表的头结点
        ListNode *head_old = head;//旧链表的头结点
        while(NULL != head_old)//遍历旧链表
        {
   
            ListNode *tmp = head_old->next;//新建个临时指针存放原来节点的next
            head_old->next = head_new;//修改旧链表节点next的指向
            head_new = head_old;//新链表的头结点往后移一个节点
            head_old = tmp;//访问下一节点旧节点
        }
        return head_new;
    }
};

(!!!)1.5 剑指 Offer 25. 合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 限制:

0 <= 链表长度 <= 1000

我的未通过的答案:

class Solution {
   
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
   
        ListNode *tmp1 = l1;
        ListNode *tmp2 = l2;
        if( NULL == tmp1)
            return l2;
        if(NULL == tmp2)
         return l1;
        while(NULL != tmp1)
        {
   
            tmp2 = l2;
            int data = tmp1 -> val;
            cout << "data is " << data << endl;
            while(NULL != tmp2)
            {
   
                if(data == tmp2->val)
                {
   
                    cout << "等于" << endl;
                    ListNode *New_node = new ListNode();
                    New_node->val = data;
                    New_node->next = tmp2->next;
                    tmp2 ->next = New_node;
                    break;
                }
                else if(data > tmp2->val)
                {
   
                    cout << "小于" << endl;
                    if(NULL == tmp2 ->next)//说明此时的tmp已经是最后一个节点了,仍然比data小,那么则将data插在最后
                    {
   
                        ListNode *New_node = new ListNode();
                        New_node->val = data;
                        New_node->next = NULL;
                        tmp2 ->next = New_node;
                        break;                        
                    }
                    else if(data < tmp2->next->val)//data的值比前一个节点小,比后一个节点打,则插在他们中间
                    {
   
                        ListNode *New_node = new ListNode();
                        New_node->val = data;
                        New_node->next = tmp2->next;
                        tmp2 ->next = New_node;
                        break;                          
                    

你可能感兴趣的:(求职过程记录,leetcode,链表,算法)