校招笔试面试---算法题1

牛牛取快递(dijkstra+邻接表存图+优先队列)

链接:https://www.nowcoder.com/questionTerminal/071695ed1d0b4e65b07eb969d212b92a
来源:牛客网

时间限制:1秒 空间限制:32768K
算法知识视频讲解

牛牛的快递到了,他迫不及待地想去取快递,但是天气太热了,以至于牛牛不想在烈日下多走一步。他找来了你,请你帮他规划一下,他最少要走多少距离才能取回快递。
输入描述:

每个输入包含一个测试用例。
输入的第一行包括四个正整数,表示位置个数N(2<=N<=10000),道路条数M(1<=M<=100000),起点位置编号S(1<=S<=N)和快递位置编号T(1<=T<=N)。位置编号从1到N,道路是单向的。数据保证S≠T,保证至少存在一个方案可以从起点位置出发到达快递位置再返回起点位置。
接下来M行,每行包含三个正整数,表示当前道路的起始位置的编号U(1<=U<=N),当前道路通往的位置的编号V(1<=V<=N)和当前道路的距离D(1<=D<=1000)。

输出描述:

对于每个用例,在单独的一行中输出从起点出发抵达快递位置再返回起点的最短距离。

示例1
输入

3 3 1 3
1 2 3
2 3 3
3 1 1

输出

7

import java.util.*;

public class Main{
    private static LinkedList<Integer[]>[] road = null;
    public static void main(String[] arags){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();
        int st = scan.nextInt();
        int en = scan.nextInt();
        road = new LinkedList[m];
        for(int i = 0; i < n; i++){
            road[i] = new LinkedList<Integer[]>();
        }
        for(int i = 0; i < m; i++){
            int x = scan.nextInt();
            int y = scan.nextInt();
            int d = scan.nextInt();
            road[x-1].add(new Integer[]{y-1, d});
        }
        System.out.println(dijkstra(st-1, en-1) + dijkstra(en - 1, st - 1));
    }
    private static int dijkstra(int st, int en){
        int n = road.length;
        int[] dis = new int[n];
        boolean[] vis = new boolean[n];
        
        for(int i = 0; i < n; i++){
            dis[i] = Integer.MAX_VALUE / 2;
        }
        PriorityQueue<Integer[]> que = new PriorityQueue<>(new Comparator<Integer[]>(){
            public int compare(Integer[] a, Integer[] b){
                return a[1] - b[1];
            }
        });
        que.add(new Integer[]{st, 0});
        dis[st] = 0;
        while(!que.isEmpty()){
            Integer[] tmp = que.poll();
            if(vis[tmp[0]]){
                continue;
            }
            vis[tmp[0]] = true;
            for(Integer[] r : road[tmp[0]]){
                if(!vis[r[0]] && tmp[1] + r[1] < dis[r[0]]){
                    dis[r[0]] = tmp[1] + r[1];
                    que.add(new Integer[]{r[0], dis[r[0]]});
                }
            }
            if(vis[en]){
                return dis[en];
            }
        }
        return dis[en];
    }
}

leetcode—3sum(双指针-单调性)

3sum
时间限制:1秒 空间限制:32768K 热度指数:10435
本题知识点: 哈希 查找 leetcode
算法知识视频讲解
题目描述

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets. 


For example, given array S = {-1 0 1 2 -1 -4},

A solution set is:
(-1, 0, 1)
(-1, -1, 2)

【分析】
这是一个典型的利用单调性的题目!如果不利用数据特点和题目特点,直接暴力达到O(N^3),即使最后一层循环可以用二分优化,也只能达到O(N^2logN),过不了OJ。

import java.util.*;

public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
        ArrayList<ArrayList<Integer>> allList = new ArrayList<ArrayList<Integer>>();
        if(num == null || num.length < 3){
            return allList;
        }
        Arrays.sort(num);
        //固定a,然后从后面找是否有两数之和是-a,利用单调性原理,用两个指针辅助,左指针右滑逐渐增大,右指针左滑,逐渐减小
        for(int i = 0; i < num.length; i++){
            if(i == 0 || (i > 0 && num[i] != num[i-1])){
                if(num[i] > 0){
                    return allList;
                }
                int l = i + 1;
                int r = num.length - 1;
                int v = -num[i];
                while(l < r){
                    if(num[l] + num[r] == v){
                        ArrayList<Integer> list = new ArrayList<>();
                        list.add(num[i]);
                        list.add(num[l]);
                        list.add(num[r]);
                        allList.add(list);
                        while(l < r && num[l] == num[l+1]){l++;}
                        while(r > l && num[r] == num[r-1]){r--;}
                        l++;
                        r--;
                    }else if(num[l] + num[r] > v){
                        r--;
                    }else{
                        l++;
                    }
                }
            }
        }
        return allList;
    }
}

leetcode—recover-binary-search-tree

时间限制:1秒 空间限制:32768K 热度指数:8127
本题知识点: 树 leetcode
算法知识视频讲解
题目描述

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O(n ) space is pretty straight forward. Could you devise a constant space solution?

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ’s Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where ‘#’ signifies a path terminator where no node exists below.

Here’s an example:

1
/
2 3
/
4

5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    
    private TreeNode first = null;
    private TreeNode second = null;
    private TreeNode pre = new TreeNode(Integer.MIN_VALUE);
    
    public void recoverTree(TreeNode root) {
        inOrder(root);
        int tmp = first.val;
        first.val = second.val;
        second.val = tmp;
    }
    private void inOrder(TreeNode root){
        if(root != null){
            inOrder(root.left);
            if(first == null && pre.val > root.val){
                first = pre;
            }
            if(first != null && pre.val > root.val){
                second = root;
            }
            pre = root;
            inOrder(root.right);
        }
    }
}

leetcode—interleaving-string

时间限制:1秒 空间限制:32768K 热度指数:9859
本题知识点: 字符串 动态规划 leetcode
算法知识视频讲解
题目描述

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 =“aabcc”,
s2 =“dbbca”,

When s3 =“aadbbcbcac”, return true.
When s3 =“aadbbbaccc”, return false.

public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if(s1 == null || s2 == null || s3 == null || s1.length() + s2.length() != s3.length()){
            return false;
        }
        return fun(s1, s2, s3, s1.length()-1, s2.length()-1,s3.length()-1);
    }
    private boolean fun(String s1, String s2, String s3, int i, int j, int k) {
        if(k < 0){
            return true;
        }
        boolean res = false;
        if(i >= 0 && s1.charAt(i) == s3.charAt(k)){
            res = fun(s1, s2, s3, i-1, j, k-1);
        }
        if(j >= 0 && res == false && s2.charAt(j) == s3.charAt(k)){
            res = fun(s1, s2, s3, i, j-1, k-1);
        }
        return res;
    }
}

N*M国际棋盘最多放多少个马互不冲突

思路参考博客地址:https://blog.csdn.net/update7/article/details/79691103
在这里插入图片描述

import java.util.*;

public class Horse {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		int min = Math.min(n, m);
		int max = Math.max(n, m);
		if(min == 1) {
			System.out.println(m);
		}else if(min == 2) {
			System.out.println(max/4*4 + Math.min(max%4, 2)*2);
		}else {
			System.out.println((min*max + 1)/2);
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值