25届嵌入式秋招准备

1.手撕

跟着大佬后面做的数组:二维数组 | 鲤鱼笔记 (lichangao.com)

前言

刷到二叉树,发现遗忘较快,开始写一些记录吧...大佬们别看,轻喷

二分查找

条件:数据是有序的;只能用来查找单个目标

边界问题解决思路:根据区间的定义是否有效

例如选择[   ,   ] 左闭右闭来解决,

(1)那么循环成立的条件就是while (left<=right),因为此时left是可以等于right的。

(2)改变边界时,if(target>nums[mid]) -----> 更新left=mid+1,因为mid已经被排除了

力扣35,704

算法复杂度一般为log n ,要是需要找第一个或者最后一个目标数,那可以根据二分查找的特性,分两次去进行查找,其中的关键点在于找到一个后,将第一个或最后一个数进行位移,从而找到首次或者最后一次出现。

力扣34

链表

相交链表

力扣160

法一:哈希表检测交点:第一个链表从头到尾insert,第二个链表去count

法二:对齐两个链表,同时查找

反转链表

力扣206

要想象原地反转,是对原链表进行操作,注意点是断开前链时,需要保存后链的第一个内容,不然链会丢失。

 ListNode* pre=NULL;
        ListNode* cur=head;
        while(cur!=NULL)
        {
            ListNode* temp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;

回文链表

方法1:存入数组后反转比较

//投机取巧法,把链表的值遍历存入数组,再将数组反转看和原数组是否相等
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int > st;
        while (head)
        {
            st.push_back(head->val);
            head=head->next;
        }
//遍历存入
        auto t=st;
        reverse(t.begin(),t.end());
        return t==st;
//反转比较
    }
};

方法2:利用栈的特性,存一半,边弹出边比较

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        stack<ListNode*> stk;
        int n=0;
        auto cur =head;
        while (head)
        {
            head=head->next;
            n++;
        }
//计算大小

        int k=(n+1)/2;
        while (k--)
        {
            stk.push(cur);
            cur=cur->next;
        }
        if (n%2) stk.pop();
//需对齐,总数为奇数的话弹出中间的
        while (cur)
        {
            if(cur->val!=stk.top()->val) return false;
            cur=cur->next;
            stk.pop();
        }
        return true;
    }
};

方法3:先找到前半个链表的末尾(快慢指针),再翻转其之后的链表,与前半部分链表进行比较

class Solution {
public:
    ListNode* endoffirsthalf(ListNode* head)
    {
        ListNode *fast=head;
        ListNode *slow=head;
        while (fast->next!=nullptr&&fast->next->next!=nullptr)
        {
            fast=fast->next->next;
            slow=slow->next;
        }
        return slow;
    }
//找到前半部分的末尾
    ListNode* reverselist(ListNode * head)
    {
        ListNode* pre=nullptr;
        ListNode* cur=head;
        while (cur!=nullptr)
        {
            ListNode *temp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
//翻转链表
    bool isPalindrome(ListNode* head) {
        if (head==nullptr)
        return true;
        ListNode* halfoffirst=endoffirsthalf(head);
        ListNode* halfofsecond=reverselist(halfoffirst->next);

        ListNode*p1=head;
        ListNode*p2=halfofsecond;
        bool result =true;
        while (result&&p2!=nullptr)
        {
            if (p1!=p2)
            result=false;
            p1=p1->next;
            p2=p2->next;
        }
//比较
        halfoffirst->next=reverselist(halfofsecond);
        return result;
    }
};

两数相加(力扣2):难点在于对sum值的处理,以及何时停止的判断

二叉树

对称二叉树

先得了解什么是对称,可以翻转的,然后在分类讨论,当两边都有数时,左的左和右的右进行比较

数组

矩阵置0:使用矩阵的第一行和第一列标记对应行列是否置零,再单独处理

动态规划

动规基础,背包问题,打家劫舍,股票问题,子序列问题

(1)dp[i][j]数组及下标的含义

(2)递推公式

(3)dp数组怎么初始化

(4)dp数组遍历顺序

(5)打印dp数组

斐波那契数,求第n个数

1  1  2  3  5  8

(1)dp[i]的含义:第i个斐波那契数的数值是dp[i]

(2)递推公式:dp[i]=dp[i-1]+dp[i-2]

(3)dp数组的初始化:dp[0]=1,dp[1]=1

(4)确定遍历顺序: 从前向后 

爬楼梯

乐,怎么还是类似斐波那契,但是递推公式的获取不算太清晰

递推公式:当前状态可以由前两个状态推导出来

为啥是初始化 需要dp(n+1)?

阶数                方法

0                       0

1                       1

2                       2

3                       3

4                       5

爬楼梯的最小花费

(1)dp[i]的含义:到第i个台阶的最小花费

(2)递推公式:

如何得到dp[i] ,由dp[i-1]跳一步或者dp[i-2]跳两步

dp[i-1]+cost[i-1]

dp[i-2]+cost[i-2]

取两者间的最小值

dp[i]=min(  dp[i-1]+cost[i-1]   ,   dp[i-2]+cost[i-2]   )

(3)dp数组的初始化:dp[1],dp[0]均为0

(4)确定遍历顺序: 从前向后 (后面由前面得到)

不同路径

 

(1)dp[i][j]的含义:从(0,0)到(i,j)有dp[i][j]的方法

(2)递推公式:dp[i][j]=dp[i-1][j]+dp[i][j-1]

(3)dp数组的初始化:最左边和最上边一定要初始化

dp[0][j]=1;

dp[i][0]=1;

(4)确定遍历顺序: 从前向后 

vector<vector<int>> dp(m, vector<int>(n, 0));

/*vector< >尖括号里放的是数组元素的类型,既然是二维数组那么第一层数组中存放的数据类型那还是一个一维数组,左边数据类型的声明已经完成。*/
/*右边的dp表示数组的名称,m表示第一层数组的元素个数,对应到我们的二维数组中就是行数。而另外的vector<int>(n, 0)则是建立一个有n个元素、每个元素大小为0的数组,作为第一层数组中的数据元素。*/
//整句话合起来就是建立了一个m行n列,每个元素初始化为0的二维数组。

获取大小

int m=dp.size();//dp.

参考资源链接:[嵌入式软件工程师笔试面试资源大揭秘](https://wenku.csdn.net/doc/57pv51k2uq?utm_source=wenku_answer2doc_content) 为了在嵌入式软件工程师的秋招笔试和面试中掌握Linux内核驱动开发的关键知识点,你需要一个高效的学习计划和高质量的学习资源。推荐参考《嵌入式软件工程师笔试面试资源大揭秘》,该资源集中了名企笔试真题、知识点总结、面试技巧等多个方面的内容,全面覆盖了Linux内核驱动开发的方方面面。 Linux内核驱动开发是一个复杂且技术要求高的领域,需要对Linux内核有深入理解。例如,熟悉内核内存管理、进程调度、设备驱动模型等,这些都是开发字符设备驱动、块设备驱动、网络设备驱动等所必须掌握的知识点。你可以通过阅读名企笔试真题来了解面试中的具体考察点,并通过知识点总结部分快速掌握这些核心概念。 另外,实践是掌握Linux内核驱动开发的关键,你可以通过模拟编程练习来加深理解,同时参考资源中的面经总结,了解面试官的期望和面试中常见的问题类型。这样,你不仅能提高编程技能,还能提高解决问题的能力,为面试做好充分准备。 在掌握了基础知识点和实践经验后,你还应该学习如何在面试中展现你的技能。资源中的笔试面试技巧部分会提供有效的策略和建议,帮助你在面试中自信地展示你的技术能力和沟通技巧。通过这些准备工作,你将更有可能在秋招笔试和面试中脱颖而出。 参考资源链接:[嵌入式软件工程师笔试面试资源大揭秘](https://wenku.csdn.net/doc/57pv51k2uq?utm_source=wenku_answer2doc_content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值