0
点赞
收藏
分享

微信扫一扫

面试中经常问到的几道算法题,诸佬们还记得如何解答嘛

醉东枫 2022-07-13 阅读 61

前言:
大家好,我是小威,入职将近两周了,昨天公司也是刚结束培训,最近也有小伙伴儿问我在公司主要做些什么,接下来告诉大家。

最近的这两周,都在培训一些公司的文化,发展方向,以及供应链相关的知识。公司安排还有近几天的业务,技术等培训。也有一些大佬问我是怎么找到的实习,其实我感觉如果看牛客上的面经看的比较多的话也容易找到,牛客还是之前学长在我什么都不懂的时候推荐给我的🤣。

所以独乐乐不如众乐乐,今天将一些面试经常问到的算法题和这么好的软件分享给大家 刷题神器

在这里插入图片描述

牛客部分使用反馈,个人感觉还不错,帮我找到了心仪的公司,希望各位伙伴儿们通过它也能提高不少🥂🥂🥂

小威再次先谢谢大家的支持了🤞🤞
在这里插入图片描述

以下正文开始

文章目录

在这里插入图片描述

🍇反转链表

这道题是面试中经常问到的,虽然是道简单题,但还是要好好理解一些。另外,小威之前面试的时候被问到过这道哈哈😂

题目:
在这里插入图片描述

在这里插入图片描述

示例1:

示例2

✨详细解析

public class Solution {
    public ListNode ReverseList(ListNode head) {
       
        if(head==null)
            return null;
        //head为当前节点,如果当前节点为空的话,那就什么也不做,直接返回null;
        ListNode pre = null;
        ListNode next = null;
        //当前节点是head,pre为当前节点的前一节点,next为当前节点的下一节点
        //需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2
        //即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了
        //所以需要用到pre和next两个节点
        //1->2->3->4->5
        //1<-2<-3 4->5
        while(head!=null){
            //做循环,如果当前节点不为空的话,始终执行此循环,此循环的目的就是让当前节点从指向next到指向pre
            //如此就可以做到反转链表的效果
            //先用next保存head的下一个节点的信息,保证单链表不会因为失去head节点的原next节点而就此断裂
            next = head.next;
            //保存完next,就可以让head从指向next变成指向pre了,代码如下
            head.next = pre;
            //head指向pre后,就继续依次反转下一个节点
            //让pre,head,next依次向后移动一个节点,继续下一次的指针反转
            pre = head;
            head = next;
        }
        //如果head为null的时候,pre就为最后一个节点了,但是链表已经反转完毕,pre就是反转后链表的第一个节点
        //直接输出pre就是我们想要得到的反转后的链表
        return pre;
    }
}

在这里插入图片描述

🍉括号生成

这道题是一道经典的dfs(深度优先)类型的题目,也是公司面试中的重点题目。
题目:
在这里插入图片描述

示例1

示例2

🍬详细解析

class Solution {
    List<String> res = new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        dfs(n, n, "");
        return res;
    }

    private void dfs(int left, int right, String curStr) {
        if (left == 0 && right == 0) { // 左右括号都不剩余了,递归终止
            res.add(curStr);
            return;
        }

        if (left > 0) { // 如果左括号还剩余的话,可以拼接左括号
            dfs(left - 1, right, curStr + "(");
        }
        if (right > left) { // 如果右括号剩余多于左括号剩余的话,可以拼接右括号
            dfs(left, right - 1, curStr + ")");
        }
    }

}

在这里插入图片描述

🍵盛水最多的容器

此题也是比较经典的题目,主要考察双指针的使用,而且也用到了贪心算法的思想。

题目:
在这里插入图片描述
如输入的height为[1,7,3,2,4,5,8,2,7],那么如下图:

在这里插入图片描述

示例1

示例2

示例3

🍻详细解析:

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param height int整型一维数组 
     * @return int整型
     */
    public int maxArea (int[] height) {
        // write code here
        int l = 0, r = height.length-1;
        int ans = 0;
        while(l<r){
            int area = Math.min(height[l], height[r]) * (r-l);
            int h = Math.min(height[l], height[r]);
            ans = Math.max(area, ans);
            while(height[l]<=h && l<r){  //当新短边大于原短边时停止
                l++;
            }
            while(height[r]<=h && l<r){  //当新短边大于原短边时停止
                r--;
            }
        }
        return ans;
    }
}

在这里插入图片描述

🍹最长公共前缀

这道题是跟字符串相关的面试中问到比较多的题,可以学习一下。

在这里插入图片描述

示例1

示例2

🥛详细解析:

先取第一个字符串当做他们的公共前缀
然后找出他和第2个字符串的公共前缀,然后再用这个找出的公共前缀分别和第3个,第4个然后进行判断

    public String longestCommonPrefix(String[] strs) {
        //边界条件判断
        if (strs == null || strs.length == 0)
            return "";
        //默认第一个字符串是他们的公共前缀
        String pre = strs[0];
        int i = 1;
        while (i < strs.length) {
            //不断的截取
            while (strs[i].indexOf(pre) != 0)
                pre = pre.substring(0, pre.length() - 1);
            i++;
        }
        return pre;
    }

在这里插入图片描述

🍓最长的括号子串

在这里插入图片描述

示例1

示例2

🥤详细解析:

import java.util.*;

public class Solution {

    public int longestValidParentheses (String s) {
        Stack<Integer> stack = new Stack<>(); // 设定栈,存储左括号
        stack.push(-1); // 压入-1,处理边界问题
        int res = 0; // 结果存储变量
        
        for (int i = 0;i < s.length();i++) {
            // 如果是左括号则直接入栈
            if (s.charAt(i) == '(') {
                stack.push(i);
            }else {
                // 如果是右括号,则弹栈
                stack.pop();
                // 判空,若栈为空,则说明i左侧已经没有可用的左括号,此时将i压入栈中,防止空栈异常
                if (stack.isEmpty()) {
                    stack.push(i);
                }else {
                    // 长度计算时无需加1,因为预先弹栈,相当于已经加过1,且在01边界上因为初始化时压入-1进栈,因此也得以解决
                    res = Math.max(res, i - stack.peek());
                }
            }
        }
        
        return res;
    }
}

在这里插入图片描述

🍒三数之和

在这里插入图片描述

示例1

示例2

🍑详细解析

class Solution {
    public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList();
        int len = nums.length;
        if(nums == null || len < 3) return ans;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len ; i++) {
            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
            if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
            int L = i+1;
            int R = len-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];
                if(sum == 0){
                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L<R && nums[L] == nums[L+1]) L++; // 去重
                    while (L<R && nums[R] == nums[R-1]) R--; // 去重
                    L++;
                    R--;
                }
                else if (sum < 0) L++;
                else if (sum > 0) R--;
            }
        }        
        return ans;
    }
}

再次感谢各位小伙伴儿们的支持🤞

举报

相关推荐

0 条评论