算法面试题汇总,字节跳动面试智力题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

提交失败,存在 Exception in thread “main” java.lang.NumberFormatException: For input string: "9646324351"问题

解题思路

// 弹出 x 的末尾数字 digit

digit = x % 10

x /= 10

// 将数字 digit 推入 rev 末尾

rev = rev * 10 + digit

大佬指点江山

private static int reverse0(int x){

int result = 0;

while(x != 0) {

int tmp = result; // 保存计算之前的结果

result = (result * 10) + (x % 10);

x /= 10;

// 将计算之后的结果 / 10,判断是否与计算之前相同,如果不同,证明发生溢出,返回0

if (result / 10 != tmp) return 0;

}

return result;

}

3、LeetCode 9.回文数


题目

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

小编菜解

public static boolean isPalindrome(int x) {

int compare = x;

if (x < 0){

return false;

}

int result = 0;

while(x != 0) {

int tmp = result; // 保存计算之前的结果

result = (result * 10) + (x % 10);

x /= 10;

}

if (result == compare) {

return true;

}

return false;

}

so easy,提交通过了。身为小菜的我,对官方大神的解法很好奇,于是,我打开了官方答案,闪瞎我的双眼,我的解法简直low爆了。

我的解法会有一个致命的问题,那就是如果反转后的数字大于int.MAX,我们将遇到整数溢出问题。

思路及算法

为了避免数字反转可能导致的溢出问题,为什么不考虑只反转数字的一半?毕竟,如果该数字是回文,其后半部分反转后应该与原始数字的前半部分相同。

现在的问题是,我们如何知道反转数字的位数已经达到原始数字位数的一半?

由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。

大佬指点江山

public static boolean isPalindrome2(int x) {

//当为负数或为以0结尾的数,反转肯定不等

if(x < 0 || (x%10 == 0 && x != 0)){

return false;

}

int revert = 0;

//当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。

while (x > revert){

revert = (revert * 10) + (x % 10);

x /= 10;

}

// 当数字长度为奇数时,我们可以通过 revert/10 去除处于中位的数字。

// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revert = 123,

// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。

return x == revert || x == revert / 10;

}

4、LeetCode 13.罗马数字转数字


题目

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值

I             1

V             5

X             10

L             50

C             100

D             500

M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。

X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。

C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

小编菜解

/**

  • 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

*/

public static int romanToInt(String s) {

Map<Character, Integer> map = new HashMap<>();

map.put(‘I’,1);

map.put(‘V’,5);

map.put(‘X’,10);

map.put(‘L’,50);

map.put(‘C’,100);

map.put(‘D’,500);

map.put(‘M’,1000);

int ret = 0;

for (int i = 0; i < s.length(); i++) {

int value = map.get(s.charAt(i));

if((i + 1) < s.length() && value < map.get(s.charAt(i + 1))){

ret = ret - value;

}else {

ret = ret + value;

}

}

return ret;

}

无情啊,居然和大神解答的一模一样,有进步。

5、LeetCode 14.最大公共前缀


题目

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

小编菜解

/**

  • 编写一个函数来查找字符串数组中的最长公共前缀。

  • 如果不存在公共前缀,返回空字符串 “”。

  • 输入:strs = [“flower”,“flow”,“flight”]

  • 输出:“fl”

*/

public static String longestCommonPrefix(String[] strs) {

Integer index = 0;

int suffixNum = 0;

//key为第一位到最后一位的下角标,value为对应位置的值

Map<Integer, Character> map = new HashMap<>();

for (int i = 0; i < strs.length; i++) {

if(!map.containsKey(index)){

map.put(index, strs[i].charAt(index));

}

if(map.containsKey(index)){

int equalNum = 0;

for (int j = i+1; j < strs.length; j++) {

if(map.get(index) == strs[j].charAt(i)){

equalNum++;

}

}

if(equalNum == strs.length-1){

suffixNum++;

}

}

index++;

}

return strs[0].substring(0,suffixNum);

}

大佬指点江山

public String longestCommonPrefix(String[] strs) {

if (strs == null || strs.length == 0) {

return “”;

}

int length = strs[0].length();

int count = strs.length;

for (int i = 0; i < length; i++) {

char c = strs[0].charAt(i);

for (int j = 1; j < count; j++) {

if (i == strs[j].length() || strs[j].charAt(i) != c) {

return strs[0].substring(0, i);

}

}

}

return strs[0];

}

6、LeetCode 20.有效的括号


题目

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

左括号必须以正确的顺序闭合。

小编菜解

public static boolean isValid(String s) {

if (s.length()%2 != 0) return false;

Map<Character,Character> hashMap = new HashMap<Character,Character>(){{

put(‘)’,‘(’);

put(‘}’,‘{’);

put(‘]’,‘[’);

}};

//“{[]}”

Queue queue = new LinkedList();

for (int i = 0; i < s.length(); i++) {

char c = s.charAt(i);

if(hashMap.containsKey©){

char t = queue.peek();

System.out.println(t);//这个地方弹出的是{

char tt = hashMap.get©;//而这个对应的是],上一处peek应该取得[

System.out.println(tt);

System.out.println(queue.peek() != hashMap.get©);

if (queue.isEmpty() || queue.peek() != hashMap.get©){

return false;

}

queue.poll();

}else{

queue.offer©;

}

}

return queue.isEmpty();

}

思路及算法

判断括号的有效性可以使用「栈」这一数据结构来解决。

当我们遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,我们可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串 ss 无效,返回 \text{False}False。为了快速判断括号的类型,我们可以使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号。

在遍历结束后,如果栈中没有左括号,说明我们将字符串 ss 中的所有左括号闭合,返回True,否则返回False。

注意到有效字符串的长度一定为偶数,因此如果字符串的长度为奇数,我们可以直接返回False,省去后续的遍历判断过程。

大佬指点江山

public static boolean isValid(String s){

int n = s.length();

if (n % 2 == 1) {

return false;

}

Map<Character, Character> pairs = new HashMap<Character, Character>() {{

put(‘)’, ‘(’);

put(‘]’, ‘[’);

put(‘}’, ‘{’);

}};

Deque stack = new LinkedList();

for (int i = 0; i < n; i++) {

char ch = s.charAt(i);

if (pairs.containsKey(ch)) {

if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {

return false;

}

stack.pop();

} else {

stack.push(ch);

}

}

return stack.isEmpty();

}

思路和我的思路完全一致,就是我使用的是单向队列,结果就是失败,加油吧!

Java中Queue和Deque的区别

7、LeetCode 26.删除有序数组中的重复项


题目

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

小编菜解

public static Integer[] removeDuplicates(Integer[] nums) {

if(nums == null || nums.length == 0){

return nums;

}

List tempList = Arrays.asList(nums);

for (int i = tempList.size() - 1; i >= 0; i–) {

Integer current = tempList.get(i);

if(i-1>0){

Integer next = tempList.get(i - 1);

if(next == current){

tempList.remove(current);

}

}

}

Integer[] ret = new Integer[tempList.size()];

tempList.toArray(ret);

return ret;

}

为什么为这样呢?我记得list是可以remove的啊,百思不得其解,查一下源码,猛然发现

Arrays的内部类ArrayList和java.util.ArrayList都是继承AbstractList,remove、add等方法在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。java.util.ArrayList重写这些方法而Arrays的内部类ArrayList没有重写,所以会抛出异常。

小编菜解改进版

public static Integer[] removeDuplicates(Integer[] nums) {

if(nums == null || nums.length == 0){

return nums;

}

List tempList = Arrays.asList(nums);

List list = new ArrayList<>(tempList);

for (int i = list.size() - 1; i >= 0; i–) {

Integer current = list.get(i);

if(i-1>0){

Integer next = list.get(i - 1);

if(next == current){

list.remove(current);

}

}

}

Integer[] ret = new Integer[list.size()];

list.toArray(ret);

return ret;

}

不报错了,结果也对,perfect!

思路及算法

相等的元素在数组中的下标一定是连续的。利用数组有序的特点,可以通过双指针的方法删除重复元素。

大佬指点江山

public static int removeDuplicates2(Integer[] nums) {

int n = nums.length;

if (n == 0) {

return 0;

}

int fast = 1, slow = 1;

while (fast < n) {

if (nums[fast] != nums[fast - 1]) {

nums[slow] = nums[fast];

++slow;

}

++fast;

}

return slow;

}

我去,无情。我的解法果然很菜,题意都没读懂,人家要的是长度,你返回一个数组,作甚??


大连跨海大桥


8、LeetCode 28.实现strStr


题目

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

小编菜解

public static int strStr(String haystack, String needle) {

if(haystack == null || !haystack.contains(needle)){

return -1;

}

if(needle == “”){

return 0;

}

int strLg = haystack.length();

int findLg = needle.length();

for (int i = 0; i < strLg; i++) {

char c = haystack.charAt(i);

if (c == needle.charAt(0) && i+findLg <= strLg){

String temp = haystack.substring(i,i + findLg);

if (temp.equals(needle)){

return i;

}

}

}

return -1;

}

没看出有什么问题,可是提交总是提示解答错误,也是无奈。

大佬指点江山

public static int strStr(String haystack, String needle) {

int strLg = haystack.length();

int findLg = needle.length();

for (int i = 0; i+findLg <= strLg; i++) {

boolean flag = true;

for (int j = 0; j < findLg; j++) {

if (haystack.charAt(i+j)!=needle.charAt(j)){

flag = false;

break;

}

}

if (true == flag){

return i;

}

}

return -1;

}

感觉大神的解法还没我的解法简单呢?可我的为何一直提交都是出错,哎,无奈。

9、LeetCode 35.搜索插入位置


题目

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

小编菜解

/**

  • 输入: nums = [1,3,5,6], target = 5

  • 输出: 2

  • 输入: nums = [1,3,5,6], target = 2

  • 输出: 1

*/

public static int searchInsert(int[] nums, int target){

for (int i = 0; i < nums.length; i++) {

if(nums[i] == target){

return i;

}

}

for (int i = 0; i < nums.length; i++) {

if(nums[i] < target){

if(i < nums.length - 1 && nums[i+1] > target){

return i+1;

}

if(nums[nums.length - 1] <target){

return nums.length;

}

}else if(nums[0] > target){

return 0;

}

}

return -1;

}

思路及算法

题意为寻找一个目标值,此类问题都可以使用二分查找。

大佬指点江山

public static int searchInsert2(int[] nums, int target){

int n = nums.length;

int left = 0;

int right = n - 1;

int index = n;

while (left <= right){

int mid = left + (right - left)/2;

if (target <= nums[mid]) {

index = mid;

right = mid - 1;

}else{

left = mid + 1;

}

}

return index;

}

10、LeetCode 58.最后一个单词的长度


题目

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。

单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

小编菜解

public static int lengthOfLastWord(String s) {

String temp = s.trim();

String[] arr = temp.split(" ");

String find = arr[arr.length-1];

return find.length();

}

大佬指点江山

public int lengthOfLastWord(String s) {

int end = s.length() - 1;

int start = 0;

while (end > 0 && s.charAt(end) == ’ '){

end–;

}

start = end;

while (start >= 0 &&s.charAt(start) != ’ '){

start–;

}

return end - start;

}

11、LeetCode 94.二叉树的中序遍历


题目

给定一个二叉树的根节点 root ,返回它的 中序 遍历。

大佬指点江山

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode() {}
    
  • TreeNode(int val) { this.val = val; }
    
  • TreeNode(int val, TreeNode left, TreeNode right) {
    
  •     this.val = val;
    
  •     this.left = left;
    
  •     this.right = right;
    
  • }
    
  • }

*/

class Solution {

public List inorderTraversal(TreeNode root) {

List res = new ArrayList();

inorder(root, res);

return res;

}

public void inorder(TreeNode root, List res) {

if (root == null) {

return;

}

inorder(root.left, res);

res.add(root.val);

inorder(root.right, res);

}

}

12、LeetCode 100.相同的树


题目

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

小编菜解

public boolean isSameTree(TreeNode p, TreeNode q) {

if (p == null && q == null) {

return true;

} else if (p == null || q == null) {

return false;

} else if (p.val != q.val) {

return false;

} else {

return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);

}

}

13、121.买卖股票的最佳时机


题目

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

小编菜解

public static int maxProfit(int[] nums) {

int max = 0;

for (int i = 0; i < nums.length; i++) {

for (int j = i + 1; j < nums.length; j++) {

int temp = nums[j] - nums[i];

if (temp > max){

max = temp;

}

}

}

return max;

}

大佬指点江山

public class Solution {

public int maxProfit(int prices[]) {

int minprice = Integer.MAX_VALUE;

int maxprofit = 0;

for (int i = 0; i < prices.length; i++) {

if (prices[i] < minprice) {

minprice = prices[i];

} else if (prices[i] - minprice > maxprofit) {

maxprofit = prices[i] - minprice;

}

}

return maxprofit;

}

}

14、LeetCode 101.对称二叉树


题目

给定一个二叉树,检查它是否是镜像对称的。

小编菜解

class Solution {

public boolean isSymmetric(TreeNode root) {

return check(root,root);

}

private boolean check(TreeNode p, TreeNode q){

if(p == null && q == null){

return true;

}

if(p == null || q == null){

return false;

}

return p.val == q.val && check(p.left,q.right) && check(p.right,q.left);

}

}


大连棒棰岛


难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ass Solution {

public boolean isSymmetric(TreeNode root) {

return check(root,root);

}

private boolean check(TreeNode p, TreeNode q){

if(p == null && q == null){

return true;

}

if(p == null || q == null){

return false;

}

return p.val == q.val && check(p.left,q.right) && check(p.right,q.left);

}

}


大连棒棰岛


难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

[外链图片转存中…(img-OwfU5ZkE-1713545431862)]

[外链图片转存中…(img-5eHPx1w2-1713545431863)]

[外链图片转存中…(img-SIKSusLc-1713545431864)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-KPDORmNe-1713545431864)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 24
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值