wanghao07456 / ChinaHadoop_AI_Offer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

小象学院AI校招班

这里为小象学院AI校招班专用刷题GitHub,旨在给每一位学员提供优质的服务
AI校招收割王

字符串 I

day1

有效回文串 题解:
首先,回文串的概念为对一个字符串而言,从前往后读和从后往前读是一样的。明确一点,空字符串也是回文串。 接下来,根据题目要求,由于字符串中存在一些特殊符号,比如逗号,在确认是否是回文串的过程中,这些特殊符号需要去除, 否则无法确认是否是回文串。 最后,我们需要两个指针,一前一后,同时往字符串的中间进行移动,每移动一位进行比较,如果相同就继续往下 比较,如果不同那么就跳出。

亲密字符串 题解:
对于两个小写字符串A和B,交换A中的两个字母之后(这两个字母可相邻也可不相邻),然后A与B相等。首先需要判断 两个字符串的长度是否相等,如果不相等,怎么交换都无法使得两个字符串相等。

  • 字符串A和B相等。如果相等,需要交换的是两个相同的元素。那么需要看是否有重复的字符
  • 字符串A和B不相等。那么需要找到不同的位置。比如 A = ’ab‘, B = 'ba',这两个字符串的第一个第二个位置都不相同,并且 对应的值交叉相等,那么交换A的第一和第二个位置的值,就可以和B相等。三个位置都不相同可以吗?不可以,三个位置不相同怎么交换 都不可以的。因此需要正好两个位置不相同,可以维护一个列表存入不相同的数

day2

最长公共前缀 题解:
"ABC","ACEF",那么最长公共前缀即为"A"。首先进行边界判断,给定的strs如果为空或者长度为0,则返回""
初始化一个前缀,可以选择strs[0]。然后对剩下的字符串进行遍历,对每个字符串的字符进行和前缀字符串的字符进行比较(可以用变量j来遍历),最后返回一个前缀在 (0,j)的子前缀即可

翻转字符串中的单词 题解:
这道题在预处理部分稍微注意下,比如给定" a b c ",那么返回结果要变为"c b a",或者" a b c",那会返回结果要变为"c b a"。实际上把给的输入取出来变为["a", "b", "c"],然后倒序放回 ["c", "b", "a"](注意这里空格为分隔符)。首先,将单词全部拿出来,使用split来做.通过StringBuidlder来构造答案。由于String在Java中不可变,而StringBuilder是可以进行改变的,方便倒序处理。当然别忘了空串判断
tips:也可以使用stack来做

数组

day1

3sum 题解:
这道题的思路也是双指针,注意使用双指针的时候一定要对数组排序。本题给的List,就要使用ArrayList把原数组的结果存入,同时在调用2Sum函数时候要注意再使用ArrayList存输出的数组,最后并入之前的结果中

旋转数组中的最小数字 题解:
二分。用两个指针分别指向数组的第一个元素和最后一个元素。按题目中旋转的规则,第一个元素应该是大于或者等于最后一个元素的(这是一般情况,代码有考虑特殊情况)。接着找到数组中间的元素,如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素应该位于中间元素的后面。这样把第一个指针指向该中间元素,缩小范围。同样,如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指向的元素,此时该数组中最小的元素应该位于中间元素的前面。这样把第二个指针指向该中间元素,缩小范围。这样,第二个指针指向刚好就是最小的元素,结束循环

day2

二维数组中的查找 题解: 由于二维数组是排好序的,既行从左到右递增,列从上到下递增。因此每次选取右上角的元素与目标数字进行比较。如果大于目标数字,那么目标只可能在左边,于是删掉右上角元素所在的列

数组中第K大的数 题解:

  • 离线算法:
    在离线处理中,可以使用Quick Select算法。在O(N)的时间内找到数组的第K大的数,然后扫描一次整个数组就可以得到前K大的数。该算法基于快排**。算法基本**:a、利用快排的分治**,求得待搜索数组的主元pivot,以主元为界分成左右两个区间 b、通过比较主元的位置,判断第K个大小的数在主元左区间还是主元右区间?还是就是主元?(还要注意边界条件的判断,有可能在边界) c、进入子区间递归调用
  • 在线算法
    对于数据流的形式,没有机会从头遍历。解决办法是考虑堆。这个问题中我们不需要支持删除操作,数据只增不减,那么那些已经排到第K名之后的数据,是再也没有机会进入前k名的,因此保留这些数据的意义不大,我们可以删掉它们。这样一来,我们需要维护一个最小堆。当我们需要决定一个整数是否能加入TopK的集合的时候,决定性的因素是:当前整数是否比Top K中的最小的数要大。因此在TopK的k个整数中,我们应该维护一个最小堆,推举出最小的整数去和数据流中新出来的整数作比较,如果新来的数更大,就踢掉堆里最小的整数,把新数加进去,反之则扔掉新数。
day3

数组中重复的数字 题解:
我们注意到数组中的数字都在0到n-1的范围内。如果这个数组中没有重复的数字,那么当数组排序之后数字i将出现在下标为i的位置。由于数组中有重复的数字,有些位置可能存在多个数字,同时有些位置可能没有数字。从头到尾依次扫描这个数组中的数字,当扫描到下标为i的数字时,首先比较这个数字(用m表示)是不是等于i,如果是,接着扫描下一个数字。如果不是,拿它和第m个数字比较。如果它和第m个数字相等,就找到了一个重复的数字(该数字的下标为i和m的位置都出现了)。如果它和第m个数字数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置。重复。

数组中的逆序对 题解:
遍历从数组的后面到数组的开头,保持一个已访问数字的排序数组。使用findIndex()查找排序数组中大于或等于目标数的第一个元素。例如,[5,2,3,6,1],当我们到达2时,我们有一个排序数组[1,3,6],findIndex()返回1,这是应该插入2的索引,也是小于2的数。然后我们将2插入到排序后的数组中,形成[1,2,3,6]

day4

连续数组的最大和 题解:
举例分析数组的规律,例如输入的数组{1,-2,3,10,-4,7,2,-5},试着从头到尾逐个累加示例数组中的每个数字.用一个sum和最大值比较

数组中出现次数超过一半的数字 题解:
数组中有一个数字出现的次数超过了数组长度的一半。那么它出现的次数比其他数字出现次数的和还要多。因此在遍历数组的时候考虑保存两个值,一个是数组中的数字,一个是出现次数。当次数为0的时候,说明前面的数字出现次数正好抵消。那么当nums[i]等于当前值的时候,count + 1,否则-1

day5

将数组排成最大数 题解:
先把整形数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。排序规则如下: 若ab > ba,则a > b 若ab < ba,则a < b 若ab = ba,则a = b

最长递增子序列 题解:
可以通过二分法查找每个当前遍历到的元素在ends中应该所处的位置,然后更新对应的位置上的元素值,然后根据i+1,就可以知道,当前元素作为子序列的末尾元素时, 前面有几个数了(i)

链表

day1

翻转链表 II 题解:
重点是找到需要翻转的区间

判断链表是否有环 题解:
快慢指针,若相遇则有环

删除链表倒数第N个节点 题解:
快慢指针,将慢指针指向slow.next = slow.next.next

day2

删除链表中的元素 题解:
链表删除的统一做法,要注意找到删除节点的前一个节点

两个链表第一个公共节点 题解:
首先遍历两个链表得到它们的长度,就知道哪个链表比较长,以及它的链表比断的链表多几个节点。在第二次遍历的时候,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到第一个相同的节点就是它们的第一个公共节点

About


Languages

Language:Java 95.8%Language:Python 4.2%