字节面试高频百题(四)

继续分享面试经常出现的算法题和解法。

第一部分见:字节面试高频百题(一)

第二部分见:字节面试高频百题(二)

第三部分见:字节面试高频百题(三)

61、反转数字

牛客 57 反转数字

  • https://www.nowcoder.com/practice/1a3de8b83d12437aa05694b90e02f47a?tpId=117

思路:

  • 注意不能引入 long 类型

  • 通过求余倒着计算结果,每加入一个字符要判断下加入这个字符会不会超限

public int reverse (int x) {

        int res = 0;
        while (x != 0) {
            int c =  x % 10;
            //判断当前字符加入结果集是否超限
            if (res > 0 && isOutMax(res, c))return 0;
            if (res < 0 && isOutMin(res, c))return 0;

            res = res * 10 + c;
            //倒数下一位
            x /= 10;

        }
        return res;
    }

    private boolean isOutMax(int target, int c) {

        if (target > Integer.MAX_VALUE / 10) return true;
        return target == Integer.MAX_VALUE / 10 && c  > Integer.MAX_VALUE % 10;

    }
    private boolean isOutMin(int target, int c) {

        if (target < Integer.MIN_VALUE / 10) return true;
        //注意取反比较
        return  target == Integer.MIN_VALUE / 10 &&
                (c - '0') > -(Integer.MIN_VALUE % 10);
    }

62、重排链表

牛客 2 重排链表:

  • https://www.nowcoder.com/practice/3d281dc0b3704347846a110bf561ef6b?tpId=196

思路:

  • 给一个单链表,将链表两两首尾相连

    • 原链表:1->2->3->4.....n->null

    • 对折后链表:1->n->2->n-1->3->n-2.......->null

    • 示例:1 2 3 4 5 6 编程 1 6 2 5 3 4

  • 找到链表中点,反转后链表,遍历前链表插入后链表节点

//找中位节点,反转后表,遍历前表,交替插入后表节点
    public void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) return ;

        //快慢指针找中位节点,p1 慢指针,p2快指针
        ListNode p1 = head, p2 = head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode pre = dummy;

        while (p2 != null && p2.next != null) {

            pre = p1;
            p1 = p1.next;
            p2 = p2.next.next;
        }

        // 此时p1走到后表的表头,需要断开前表和后表连接
        pre.next = null;

        //以p1为表头反转后表,返回表头
        ListNode head2 = reverse(p1);

        //p1指向前表表头,p2指向后表表头,遍历前表,交替插入后表节点
        p1 = head;
        p2 = head2;
        while (p1 != null) {
            ListNode head1Next = p1.next;
            ListNode head2Next = p2.next;
            p1.next = p2;
            p2.next = head1Next;

            //指针继续前进
            p1 = head1Next;
            p2 = head2Next;
        }

        //p2如果还有节点要连上来
        if (p2 != null) {
            p1 = head;
            dummy.next = head;
            pre = dummy;
            while (p1 != null) {
                pre = p1;
                p1 = p1.next;
            }
            pre.next = p2;
        }

    }

    //反转链表返回反转后的表头节点
    private ListNode reverse(ListNode head){

        if(head == null || head.next == null) return head;

        ListNode last  = reverse(head.next);

        head.next.next = head;
        head.next = null;

        return last;

    }

63、矩阵元素查找

牛客 86 矩阵元素查找:

  • https://www.nowcoder.com/practice/3afe6fabdb2c46ed98f06cfd9a20f2ce?tpId=117

思路:

  • 行维度倒序剪枝

  • 行维度从后往前,当前元素值比目标值大,意味着这一列都比它大,没必要循环

public int[] findElement (int[][] mat, int n, int m, int x) {

        int[] ans = new int[2];
        //行维度从后往前,当前元素值比目标值大,意味着这一列都比它大,没必要循环
        for (int i = n - 1; i >= 0; i--) {
            if (mat[i][0] > x) {
                continue;
            }
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == x) {
                    ans[0] = i;
                    ans[1] = j;
                }
            }
        }
        return ans;
    }

64、缺失的第一个正整数

牛客 30 缺失的第一个正整数

  • https://www.nowcoder.com/practice/50ec6a5b0e4e45348544348278cdcee5?tpId=196

思路:

  • 排序,遍历时非正正数跳过,正整数和递增的目标数比对,一致目标数递增,不一致返回当前目标数

public int minNumberDisappeared (int[] nums) {

        if(nums == null || nums.length == 0) return 1;
        
        Arrays.sort(nums);

        int n = 1;
        for(int i = 0; i < nums.length;i++){
            
            if(nums[i] <= 0) continue;
            //出现了正整数
            if(nums[i] == n) {
                n++;
                continue;
            }else {
                return n;
            }
        }
        return n;
    }

65、丢失的数字

力扣 268 丢失的数字:

  • https://leetcode.cn/problems/missing-number/description/

思路:

  • 排序+遍历

  • 进阶:排序+二分

public int missingNumber(int[] nums) {

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

            if (nums[i] == n) {
                n++;
                continue;
            } else {
                return n;
            }
        }
        return n;
    }

66、链表的奇偶重排

力扣 328/牛客 133 链表的奇偶重排:

  • https://www.nowcoder.com/practice/02bf49ea45cd486daa031614f9bd6fc3?tpId=196

  • https://leetcode.cn/problems/odd-even-linked-list/description/

思路:

  • 合并链表的思路,分别把奇数节点和偶数节点合并到新链表中

public ListNode oddEvenList (ListNode head) {
        
        if (head == null || head.next == null) return head;

        ListNode dummy = new ListNode(-1);
        //p1 奇数位,p2偶数位
        ListNode p = dummy, p1 = head, p2 = head.next;
        //奇数位取每两步的值
        while (p1 != null && p1.next != null) {

            p.next = new ListNode(p1.val);
            p1 = p1.next.next;
            p = p.next;
        }

        //p1还没被连接
        if (p1 != null) {
            p.next = new ListNode(p1.val);
            p = p.next;
        }

        //偶数位取每两步的值
        while (p2 != null && p2.next != null) {

            p.next = new ListNode(p2.val);
            p2 = p2.next.next;
            p = p.next;

        }

        //p2还没被连接
        if (p2 != null) {
            p.next = p2;
        }

        return dummy.next;
    }

67、二叉树中的最大路径和

力扣 124/牛客 6 二叉树中的最大路径和:

  • https://www.nowcoder.com/practice/da785ea0f64b442488c125b441a4ba4a?tpId=196

  • https://leetcode.cn/problems/binary-tree-maximum-path-sum/description/

思路:

  • 左右子树贡献求最大,注意负数情况的处理,函数返回节点贡献值选左子树或者由子树

private int res = Integer.MIN_VALUE;

    public int maxPathSum (TreeNode root) {
        
        if(root == null) return 0;
        traverse(root);
        return res;
    }

    //遍历二叉树,返回以root为根节点的最大路劲和
    private int traverse(TreeNode root){
        if(root == null) return 0;

        //有负数情况,要取大于0的
        int leftMax = traverse(root.left);
        leftMax = Math.max(leftMax,0);
        int rightMax = traverse(root.right);
        rightMax = Math.max(rightMax,0);

        //已有最大值结果和当前路径和比较
        int curMax = leftMax + rightMax + root.val;
        res = Math.max(res,curMax);

        //返回节点的最大贡献值(此节点要么采用左子树做路径,要么采用右子树做路径)
        return root.val + Math.max(leftMax,rightMax);
    }

68、对称二叉树

力扣 101/牛客 16 对称的二叉树:

  • https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=196

  • https://leetcode.cn/problems/symmetric-tree/description/

思路:

  • 二叉树后续遍历:

    • 节点比较

  • 层序遍历借助栈

public boolean isSymmetrical (TreeNode pRoot) {

        return traverse(pRoot, pRoot);
    }

    private boolean traverse(TreeNode root1, TreeNode root2) {

        if (root1 == null && root2 == null) return true;

        if (root1 == null || root2 == null) return false;

        //当前层结果
        boolean curRes = root1.val == root2.val;
        //root1 左节点和 root2 右节点比较
        boolean leftRight = traverse(root1.left, root2.right);
        //root1 右节点和 root2 左节点比较
        boolean rightLeft = traverse(root1.right, root2.left);

        return curRes && leftRight && rightLeft;
    }

69、括号生成

牛客 26 括号生成

  • https://www.nowcoder.com/practice/c9addb265cdf4cdd92c092c655d164ca?tpId=196

思路:

  • 递归树,左子树处理左括号,右子树处理有括号

  • left 为当前左括号个数,right 为当前右括号个数,n 对括号。递归树终止条件是 left==n&&left==right

ArrayList<String> res = new ArrayList<>();

    public ArrayList<String> generateParenthesis (int n) {

        traverse(n, 0, 0, "");
        return res;
    }

    //left 为当前左括号个数,right 为当前右括号个数,n 对括号。递归树终止条件是 left==n&&left==right
    private void traverse(int n, int left, int right, String cur) {

        //左括号比n大或者右括号比左括号大,非法
        if (left > n || right > left) return;

        if (left == n && left == right) {
            res.add(cur);
            return;
        }

        //追加左括号
        traverse(n, left + 1, right, cur + "(");
        //追加右括号
        traverse(n, left, right + 1, cur + ")");
    }

70、顺时针旋转矩阵

牛客 18 顺时针旋转矩阵

  • https://www.nowcoder.com/practice/2e95333fbdd4451395066957e24909cc?tpId=196

思路:

  • 对角线置换+水平前后置换

//对角线置换+水平前后置换
    public int[][] rotateMatrix (int[][] mat, int n) {
        //矩阵转置
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                //交换上三角与下三角对应的元素
                int temp = mat[i][j];
                mat[i][j] = mat[j][i];
                mat[j][i] = temp;
            }
        }
        //每行翻转
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n / 2; j++) {
                int temp = mat[i][j];
                mat[i][j] = mat[i][n - j - 1];
                mat[i][n - j - 1] = temp;
            }
        }
        return mat;
    }

71、删除有序链表中重复的元素-I

力扣 83/牛客 25 删除有序链表中重复的元素-I

  • https://leetcode.cn/problems/remove-duplicates-from-sorted-list/

  • https://www.nowcoder.com/practice/c087914fae584da886a0091e877f2c79?tpId=196

思路:

  • 快慢指针。都初始化 head,遍历快指针,当快慢指针值不等时,慢指针直接连接不等值的快指针,此时慢指针再推进,达到跳过重复数字的效果。

  • 注意循环结束要对慢指针跳过后面重复元素的连接: 2-3-3 的case。

public ListNode deleteDuplicates(ListNode head) {

        if(head == null) return null;

        ListNode slow = head,fast = head;

        while(fast != null){
            if(slow.val != fast.val){
                //对应数组快慢指针操作中的 nums[slow] = nums[fast]
                slow.next = fast;
                //对应数组快慢指针操作中的 slow++
                slow = slow.next;
            }

            fast = fast.next;
        }

        // 断开与后面重复元素的连接
        slow.next = null;

        return head;

    }

72、加起来和为目标值的组合

牛客 238 加起来和为目标值的组合:

  • https://www.nowcoder.com/practice/172e6420abf84c11840ed6b36a48f8cd?tpId=196

思路:

  • 回溯法

public ArrayList<ArrayList<Integer>> combinationCount (int target, int[] nums) {
        
        if (nums.length == 0) return ans;
        Arrays.sort(nums);//排序后便于剪枝

        backtrack(target, nums, 0, 0);
        return ans;
    }

    public void backtrack(int target, int[] nums, int sum, int start) {
        
        //满足条件追加结果
        if (target == sum) {
            ans.add(new ArrayList<>(path));
            return ;
        }

        //for 选择 in 选择列表
        for (int i = start; i < nums.length; i++) {
            
            //剪枝,结果和已经大于目标值,无需下一轮递归
            if (sum + nums[i] > target) break;

            //做选择
            path.addLast(nums[i]);
            sum = sum + nums[i];

            //递归调用
            backtrack(target, nums, sum, i);
            
            //撤销选择
            sum = sum - nums[i]; 
            path.removeLast();
        }
    }

73、左边界二分查找

牛客 105 二分查找-II:

  • https://www.nowcoder.com/practice/4f470d1d3b734f8aaf2afb014185b395

思路:

  • 等值时收缩右边界

public int search (int[] nums, int target) {

        int left = 0, right = nums.length - 1;


        int res = -1;
        while (left <= right) {
            
            int mid = left + (right - left) / 2;
            
            
            if (nums[mid] < target) {
                //搜索边界变为 [mid+1,right]
                left = mid + 1;
                
            } else if (nums[mid] > target) {
                //搜索边界变为 [left,mid-1]
                right = mid -1;
            
            }else if(nums[mid] == target){
                res = mid;
                //收缩右边界
                right = mid -1;
            }
        }

        return res;

    }

74、序列化二叉树

力扣 297/牛客 123 序列化二叉树

  • https://leetcode.cn/problems/serialize-and-deserialize-binary-tree/description/

  • https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=196&tqId=37116

思路:

  • 在相应位置做逻辑处理

【前序】

private String SEP = ",";
    private String NULL = "#";

    //先序序列化
    String Serialize(TreeNode root) {

        StringBuilder sb = new StringBuilder();
        traverse(root, sb);
        return sb.toString();
    }

    void traverse(TreeNode root, StringBuilder sb) {

        if (root == null) {
            sb.append(NULL).append(SEP);
            return;
        }

        sb.append(root.val).append(SEP);
        traverse(root.left, sb);
        traverse(root.right, sb);
    }

    
    TreeNode Deserialize(String str) {
       
        LinkedList<String> nodes = new LinkedList<>();
        
        for(String s : str.split(SEP)){
            nodes.add(s);
        }

        return Deserialize(nodes);

    }

    TreeNode Deserialize(LinkedList<String> nodes){
        
        if(nodes.isEmpty()) return null;

        String rootVal = nodes.removeFirst();
        if(rootVal.equals(NULL)) return null;
        TreeNode root = new TreeNode(Integer.parseInt(rootVal));

        root.left = Deserialize(nodes);
        root.right = Deserialize(nodes);

        return root;
    }

【层序】

String SEP = ",";
    String NULL = "#";

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {

        if (root == null)
            return "";

        StringBuilder sb = new StringBuilder();

        // 初始化队列,将 root 加入队列
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);

        while (!q.isEmpty()) {
            TreeNode cur = q.poll();

            // 层序遍历代码位置
            if (cur == null) {
                sb.append(NULL).append(SEP);
                continue;
            }

            sb.append(cur.val).append(SEP);

            q.offer(cur.left);
            q.offer(cur.right);

        }

        return sb.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {

        if (data.isEmpty())
            return null;

        String[] nodes = data.split(SEP);
        // 第一个元素就是 root 的值
        TreeNode root = new TreeNode(Integer.parseInt(nodes[0]));

        // 队列q 记录父节点,将root加入队列
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);

        for (int i = 1; i < nodes.length;) {
            // 队列中存的都是父节点
            TreeNode parent = q.poll();

            // 父节点对应的左侧子节点的值
            String left = nodes[i++];
            if (!left.equals(NULL)) {
                parent.left = new TreeNode(Integer.parseInt(left));
                q.offer(parent.left);
            } else {
                parent.left = null;
            }

            // 父节点对应的右侧子节点的值
            String right = nodes[i++];
            if (!right.equals(NULL)) {
                parent.right = new TreeNode(Integer.parseInt(right));
                q.offer(parent.right);
            } else {
                parent.right = null;
            }
        }

        return root;

    }

75、字符串变形

牛客 89 字符串变形:

  • https://www.nowcoder.com/practice/c3120c1c1bc44ad986259c0cf0f0b80e?tpId=196

思路:

  • 空格拆子字符串,针对子字符串做大小写转换

public String trans (String s, int n) {

        String[] arr = s.split(" ", -1);
        StringBuilder res = new StringBuilder();

        for (int i = arr.length - 1; i >= 0 ; i--) {

            res.append(upperLowerReverse(arr[i]));

            if (i == 0) break;

            res.append(" ");
        }

        return res.toString();

    }

    //字符串中大小写字母反转
    private String upperLowerReverse(String str) {

        char[] strArr = str.toCharArray();

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

            if (Character.isUpperCase(strArr[i])) {
                strArr[i] = Character.toLowerCase(strArr[i]);
            } else {
                strArr[i] = Character.toUpperCase(strArr[i]);
            }
        }
        return new String(strArr);
    }

76、环形链表的约瑟夫问题

牛客 132 环形链表的约瑟夫问题:

  • https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a?tpId=196

思路:

  • 构建一个环形链表,指针符合要求则删除节点

public int ysf (int n, int m) {
        
        //构建一个环形链表,指针符合要求则删除节点
        ListNode head = buildCycleList(n);

        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode pre = dummy;
        ListNode p = head;
        int cnt = 0;        
        while(p.next != p){

            cnt++;
            if(cnt == m){
                //删除当前节点
                pre.next = p.next;
                //清空报名
                cnt = 0;
            }
            //更新前驱节点和移动指针
            pre = p;
            p = p.next;

        }

        return p.val;
    }

    public ListNode buildCycleList(int n){

        ListNode head = new ListNode(1);
        ListNode p = head;
        for(int i = 2;i <=n;i++){
            p.next = new ListNode(i);
            p = p.next;
        }
        //成环
        p.next = head;

        return head;
    }

    class ListNode{

        public int val;
        public ListNode next;

        public ListNode(int val){
            this.val = val;
        }
    }

77、最大数

牛客111 最大数:

  • https://www.nowcoder.com/practice/fc897457408f4bbe9d3f87588f497729?tpId=196

思路:

  • 整型转字符串,排序并拼接

public String solve (int[] nums) {
        
        ArrayList<String> list = new ArrayList<>();
        
        //将整型的数字转化为字符串
        for (int i = 0; i < nums.length; i ++) {
            list.add(String.valueOf(nums[i]));
        }
        //排序:字典降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return (b + a).compareTo(a + b);
            }
        });

        //这个地方需要注意如果第一个字符串已经是0了,那么直接输出0
        if (list.get(0).equals("0")) return "0";

        //结果字符串
        StringBuilder res = new StringBuilder();
        //将排序好后的字符串一次相加就是最终的结果 
        for (int i = 0; i < list.size();i ++) { 
            res.append(list.get(i));
        }
        return res.toString();
    }

78、验证 IP 地址

牛客 113 验证 IP 地址:

  • https://www.nowcoder.com/practice/55fb3c68d08d46119f76ae2df7566880?tpId=196

思路:

  • 根据 IP 特点做针对性检查

boolean isIPv4 (String IP) {
        if (IP.indexOf('.') == -1) {
            return false;
        }
        String[] s = IP.split("\\.");
        //IPv4必定为4组
        if (s.length != 4)
            return false;
        for (int i = 0; i < s.length; i++) {
            //不可缺省,有一个分割为零,说明两个点相连
            if (s[i].length() == 0)
                return false;
            //比较数字位数及不为零时不能有前缀零
            if (s[i].length() < 0 || s[i].length() > 3 || (s[i].charAt(0) == '0' &&
                    s[i].length() != 1))
                return false;
            int num = 0;
            //遍历每个分割字符串,必须为数字
            for (int j = 0; j < s[i].length(); j++) {
                char c = s[i].charAt(j);
                if (c < '0' || c > '9')
                    return false;
                //转化为数字比较,0-255之间
                num = num * 10 + (int)(c - '0');
                if (num < 0 || num > 255)
                    return false;
            }
        }
        return true;
    }
    boolean isIPv6 (String IP) {
        if (IP.indexOf(':') == -1) {
            return false;
        }
        String[] s = IP.split(":", -1);
        //IPv6必定为8组
        if (s.length != 8) {
            return false;
        }
        for (int i = 0; i < s.length; i++) {
            //每个分割不能缺省,不能超过4位
            if (s[i].length() == 0 || s[i].length() > 4) {
                return false;
            }
            for (int j = 0; j < s[i].length(); j++) {
                //不能出现a-fA-F以外的大小写字符
                char c = s[i].charAt(j);
                boolean expr = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' &&
                               c <= 'F') ;
                if (!expr) {
                    return false;
                }
            }
        }
        return true;
    }
    
    public String solve (String IP) {

        if (isIPv4(IP))
            return "IPv4";
        else if (isIPv6(IP))
            return "IPv6";
        return "Neither";
    }

79、兑换零钱

力扣 322/牛客 126 兑换零钱(一):

  • https://www.nowcoder.com/practice/3911a20b3f8743058214ceaa099eeb45?tpId=196

  • https://leetcode.cn/problems/coin-change/description/

思路:

  • 动态规划 子问题

int[] memo;

    public int coinChange(int[] coins, int amount) {

        memo = new int[amount + 1];

        Arrays.fill(memo, -66);

        return dp(coins, amount);

    }

    // 返回金额为amount需要的最小硬币数
    int dp(int[] coins, int amount) {

        if (amount == 0)
            return 0;
        if (amount < 0)
            return -1;

        if (memo[amount] != -66)
            return memo[amount];

        int res = Integer.MAX_VALUE;

        for (int coin : coins) {

            int subProNum = dp(coins, amount - coin);

            if (subProNum == -1)
                continue;

            res = Math.min(res, subProNum + 1);
        }

        memo[amount] = res == Integer.MAX_VALUE ? -1 : res;
        return memo[amount];
    }

80、数组中的逆序对

牛客 118 数组中的逆序对:

  • https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=196

思路:

  • 归并排序过程中计算数量

int count = 0;
    public int InversePairs(int [] array) {

        // 长度小于2则无逆序对
        if (array.length < 2) return 0;
        
        // 进入归并
        mergeSort(array, 0, array.length - 1);
        
        return count;
    }

    public void mergeSort(int[] array, int left, int right) {
        
        // 找分割点
        int mid = left + (right - left) / 2;
        
        if (left < right) {
            // 左子数组
            mergeSort(array, left, mid);
            // 右子数组
            mergeSort(array, mid + 1, right);
            // 并
            merge(array, left, mid, right);
        }
    }

    public void merge(int[] array, int left, int mid, int right) {
        
        // 创建临时数组,长度为此时两个子数组加起来的长度
        int[] arr =  new int[right - left + 1];
        
        // 临时数组的下标起点
        int c = 0;
        
        // 保存在原数组的起点下标值
        int s = left;
        
        // 左子数组的起始指针
        int l = left;
        
        // 右子数组的起始指针
        int r = mid + 1;
        while (l <= mid && r <= right ) {
            // 当左子数组的当前元素小的时候,跳过,无逆序对
            if (array[l] <= array[r]) {
                // 放入临时数组
                arr[c] = array[l];
                // 临时数组下标+1
                c++;
                // 左子数组指针右移
                l++;
            } else { // 否则,此时存在逆序对
                // 放入临时数组
                arr[c] = array[r];
                // 逆序对的个数为    左子数组的终点- 当前左子数组的当前指针
                count += mid + 1 - l;
                count %= 1000000007;
                // 临时数组+1
                c++;
                // 右子数组的指针右移
                r++;
            }
        }

        // 左子数组还有元素时,全部放入临时数组
        while (l <= mid)
            arr[c++] = array[l++];
        // 右子数组还有元素时,全部放入临时数组
        while (r <= right)
            arr[c++] = array[r++];
        // 将临时数组中的元素放入到原数组的指定位置
        for (int num : arr) {
            array[s++] = num;
        }
    }

我是蜗牛,大厂程序员,专注技术原创和个人成长,正在互联网上摸爬滚打。欢迎关注我,和蜗牛一起成长,我们一起牛~下期见!

推荐阅读:

字节面试高频百题(二)

《Java 工程师成神之路》.pdf

点阅读原文发现更多Java资源宝藏~

 
 
 
 
 
 
 
 
点分享
点收藏
点点赞
点在看
  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛互联网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值