Google算法面试【面试】

code1

https://www.bilibili.com/video/BV1yC4y127rc

给你一些街区和你喜欢去的地方
街区中包含是否有没有你所喜欢去的地方

返回你可以到达这些地方的最大距离中值最小的街道下标

Blocks =[
{
"gym": false,
"school": true
"store": false,
},
{
"gym": true,
"school": false
"store": false
},
{
"gym": true,
"school": true
"store": false,
},
{
"gym": false,
"school": true
"store": false
},
{
"gym": false,
"school": true,
"store": true
}


Reqs =["gym","school", "store"]
Answer:3

代码

package google;

import java.util.Arrays;

/*
https://www.bilibili.com/video/BV1yC4y127rc


给你一些街区和你喜欢去的地方
街区中包含是否有没有你所喜欢去的地方

返回你可以到达这些地方的最大距离中最小的街道下标
Answer:3


Blocks =[
{
"gym": false,
"school": true
"store": false,
},
{
"gym": true,
"school": false
"store": false
},
{
"gym": true,
"school": true
"store": false,
},
{
"gym": false,
"school": true
"store": false
},
{
"gym": false,
"school": true,
"store": true
}


Reqs =["gym","school", "store"]




//0 * 0 * *  1 0 4 4
//1 0 1 * *  0 1 3 3
//2 0 0 * *  0 0 2 2
//3 1 0 * *  1 0 1 1
//4 2 0 0 2




 */
public class Main1 {


    public static void main(String[] args) {
//        ArrayList<HashMap<String,Boolean>> blocks=new ArrayList<>();
//        ArrayList<String> reqs=new ArrayList<>();

        //简单数据表示
        int[][] blocks={
                {0,1,0},
                {1,0,0},
                {1,1,0},
                {0,1,0},
                {0,1,1}
        };

        int[] reqs={0,1,2};

        int n=blocks.length;
        int m=blocks[0].length;

        //第m位表示到所需地点的最大距离
        int[][] dp=new int[n][m+1];
        for (int i = 0; i < n; i++) {
            Arrays.fill(dp[i],Integer.MAX_VALUE);
        }

        //单独处理第0个
        for (int j=0;j<m;j++){
            if(blocks[0][j]==1){
                dp[0][j]=0;
            }
        }

        //从左到右
        for (int i=1;i<n;i++){
            dp[i][m]=0;
            for(int j=0;j<m;j++){
                if(blocks[i][j]==1){
                    dp[i][j]=0;
                }else {
                    if(dp[i-1][j]!=Integer.MAX_VALUE){
                        dp[i][j]=Math.min(dp[i][j],dp[i-1][j]+1);
                    }
                }
                dp[i][m]=Math.max(dp[i][m],dp[i][j]);
            }
        }

        //从右到左
        for (int i=n-2;i>=0;i--){
            dp[i][m]=0;
            for(int j=0;j<m;j++){
                if(blocks[i][j]==1){
                    dp[i][j]=0;
                }else {
                    if(dp[i+1][j]!=Integer.MAX_VALUE){
                        dp[i][j]=Math.min(dp[i][j],dp[i+1][j]+1);
                    }
                }
                dp[i][m]=Math.max(dp[i][m],dp[i][j]);
            }
        }

        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(dp[i]));
        }

        int ans=dp[0][m];
        int ansIndex=0;
        for (int i = 1; i < n; i++) {
            if(dp[i][m]<ans){
                ans=dp[i][m];
                ansIndex=i;
            }
        }
        System.out.println(ansIndex);
    }
}

code2

https://www.bilibili.com/video/BV1wM411Z7ZQ

0代表海洋,1代表陆地
删除和边界邻接的岛屿

[
    [1,0,0,0,0,0],
    [0,1,0,1,1,1],
    [0,0,1,0,1,0],
    [1,1,0,0,1,0],
    [1,0,1,1,0,0],
    [1,0,0,0,0,1]
]



[
    [0,0,0,0,0,0],
    [0,1,0,0,0,0],
    [0,0,1,0,0,0],
    [0,0,0,0,0,0],
    [0,0,1,1,0,0],
    [0,0,0,0,0,0]
]

代码

package google;


import java.util.Arrays;

/*

https://www.bilibili.com/video/BV1wM411Z7ZQ

0代表海洋,1代表陆地
删除和边界邻接的岛屿


[
    [1,0,0,0,0,0],
    [0,1,0,1,1,1],
    [0,0,1,0,1,0],
    [1,1,0,0,1,0],
    [1,0,1,1,0,0],
    [1,0,0,0,0,1]
]



[
    [0,0,0,0,0,0],
    [0,1,0,0,0,0],
    [0,0,1,0,0,0],
    [0,0,0,0,0,0],
    [0,0,1,1,0,0],
    [0,0,0,0,0,0]
]
 */
public class Main2 {

    public static void main(String[] args) {
        int[][] martix={
                {1,0,0,0,0,0},
                {0,1,0,1,1,1},
                {0,0,1,0,1,0},
                {1,1,0,0,1,0},
                {1,0,1,1,0,0},
                {1,0,0,0,0,1}
        };

        int[][] res=removeIslands(martix);
        for (int[] r:res) {
            System.out.println(Arrays.toString(r));
        }

    }



    static int n;
    static int m;

    //队列
    static int[][] queue;
    static int l;
    static int r;

    //方向数组(i,i+1) 下,左,上,右
    static int[] moved={1,0,-1,0,1};
    //也可以用二维数组表示
    //{{1,0},{-1,0},{0,1},{0,-1}}

    //广度优先遍历
    private static int[][] removeIslands(int[][] martix) {


        //初始化
        n=martix.length;
        m=martix[0].length;

        //记录需要删除的岛屿坐标,代表删除的为1
        int[][] removed=new int[n][m];

        //数组代替队列
        queue=new int[n*m][2];
        l=r=0;


        //队列中添加边界为1的岛屿
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if(i==0||j==0||i==n-1||j==m-1){
                    if(martix[i][j]==1){
                        queue[r++]=new int[]{i,j};
                    }
                }
            }
        }

        //队列不为空
        while (l<=r){
            int[] cur =queue[l++];
            removed[cur[0]][cur[1]]=1;
            for (int i = 0; i < 4; i++) {
                int nextX= cur[0]+moved[i];
                int nextY= cur[1]+moved[i+1];
                //不出边界
                if (nextX>=0&&nextX<n&&nextY>=0&&nextY<m){
                    //没有被访问的1
                    if(removed[nextX][nextY]!=1&&martix[nextX][nextY]==1) {
                        queue[r++] = new int[]{nextX, nextY};
                    }
                }
            }

        }


        //返回删除之后的岛屿只需要异或就行
        for(int i=0;i<n;i++){
            for (int j=0;j<m;j++){
                martix[i][j]^=removed[i][j];
            }
        }
        return martix;

    }

}

code3

https://www.bilibili.com/video/BV1YN4y1b7mC

电话表入下

---------------------
|  1   |  2  |  3   |
|      | abc | def  |
---------------------
|  4   |  5  |  6   |
| ghi  | jkl | mno  |
---------------------
|  7   |  8  |  9   |
| pqrs | tuv | wxyz |
---------------------
|      |  0  |      |
|      |     |      |
---------------------

给你一个电话号码,和一些单词
找出哪些单词在电话号码中出现

phoneNumber="3662277"
words = ["foo", "bar", "baz", "foobar", "emo", "cap", "car", "cat"]

Output: ["bar", "cap", "car", "emo", "foo", "foobar"]

代码

package google;


import java.util.ArrayList;


/*

https://www.bilibili.com/video/BV1YN4y1b7mC


电话表入下

---------------------
|  1   |  2  |  3   |
|      | abc | def  |
---------------------
|  4   |  5  |  6   |
| ghi  | jkl | mno  |
---------------------
|  7   |  8  |  9   |
| pqrs | tuv | wxyz |
---------------------
|      |  0  |      |
|      |     |      |
---------------------

给你一个电话号码,和一些单词
找出哪些单词在电话号码中出现

phoneNumber="3662277"
words = ["foo", "bar", "baz", "foobar", "emo", "cap", "car", "cat"]

Output: ["bar", "cap", "car", "emo", "foo", "foobar"]

 */
public class Main3 {
    //字母对应数字
    static int[] chars={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};


    public static void main(String[] args) {
        String phoneNumber="3662277";
        String[] words = {"foo", "bar", "baz", "foobar", "emo", "cap", "car", "cat"};

        int m= words.length;
        //把单词表转为号码字符串就好了
        String[] wordNums=new String[m];
        for (int i = 0; i < m; i++) {
            wordNums[i]="";
            for (int j = 0; j < words[i].length(); j++) {
                wordNums[i]+=(chars[ words[i].charAt(j)-'a']);
            }
        }

        ArrayList<String> ans=new ArrayList<>();
        for (int i=0;i<m;i++){
            if(phoneNumber.contains(wordNums[i])){//用java API 字符串查找
                ans.add(words[i]);
            }
        }

        System.out.println(ans);
    }

    //都转为数字,构建前缀树查找
//        int n=phoneNumber.length();
//        int m= words.length;
//        int[] phone=new int[n];
//        for (int i = 0; i < n; i++) {
//            phone[i]=phoneNumber.charAt(i)-'0';
//        }
//        System.out.println(Arrays.toString(phone));
//
//        ArrayList<Integer>[] wordNums=new ArrayList[m];
//        for (int i = 0; i < m; i++) {
//            wordNums[i]=new ArrayList<Integer>();
//            for (int j = 0; j < words[i].length(); j++) {
//                wordNums[i].add(chars[ words[i].charAt(j)-'a']);
//            }
//        }
//
//        for (ArrayList<Integer> word:wordNums) {
//            System.out.println(word);
//        }
}

code4

https://www.bilibili.com/video/BV1nb4y1G7Pj

给一个PI若干位s
给一个喜欢的数组favArr
求在s中加入最少得空格数,使得划分后的词都出现在favArr中

Sample Input:
    - 3141592653589793238462643383279
    - ['314','49','9001',15926535897','14','9323','8462643383279','4','793']
Sample Output:
    - 3(314 15926535897 9323 8462643383279)
package google;


import java.util.Arrays;
import java.util.HashMap;

/*

https://www.bilibili.com/video/BV1nb4y1G7Pj

给一个PI若干位s
给一个喜欢的数组favArr
求在s中加入最少得空格数,使得都出现在favArr中

Sample Input:
    - 3141592653589793238462643383279
    - ['314','49','9001',15926535897','14','9323','8462643383279','4','793']
Sample Output:
    - 3(314 15926535897 9323 8462643383279)

 */
public class Main1227 {

    public static void main(String[] args) {
        String s="3141592653589793238462643383279";
        String[] favArr={"314","49","9001","15926535897","14","9323","8462643383279","4","793"};

//        String s="31415926";
//        String[] favArr={"3","141","5926"};

        int res1=minSpaces1(s,favArr);
        System.out.println(res1);

        int res2=minSpaces2(s,favArr);
        System.out.println(res2);


    }


    static HashMap<String,Boolean> exists=new HashMap<>();
    static char[] pi;
    static int[] dp;
    static int n;

    //时间复杂度O(n^2)
    //空间复杂度
    //exists表O(n)
    //dp表 O(n)
    //尝试递归
    static int minSpaces1(String s,String[] favArr){
        Main1227.pi=s.toCharArray();
        n=s.length();

        dp=new int[n];
        Arrays.fill(dp,-1);

        for (String a:favArr){
            exists.put(a,true);
        }

        //空格数=词数-1
        return check(0)-1;
    }


    //最小的划分词数
    //空格树=词数-1
    //s[pos...]的最小划分数
    //不存在返回Integer.MAX_VALUE

    static int check(int pos){
        if(pos==n){
            return 0; //base case
        }
        if(dp[pos]!=-1){
            return dp[pos];
        }


        int ans=Integer.MAX_VALUE;
        String cur="";

        for(int j=pos;j<n;j++){
            cur+=pi[j];
            if(exists.getOrDefault(cur,false)){
                int other=check(j+1);
                if(other!=Integer.MAX_VALUE){
                    ans=Math.min(ans,1+other);
                }
            }
        }

        dp[pos]=ans;
        return ans;
    }



    //时间复杂度O(n^2)
    //空间复杂度
    //exists表O(n)
    //dp表O(n)
    //严格位置依赖的动态规划
    static int minSpaces2(String s,String[] favArr){
        char[] pi=s.toCharArray();
        int n=pi.length;
        int[] dp=new int[n+1];

        HashMap<String,Boolean> exists=new HashMap<>();
        for (String a:favArr){
            exists.put(a,true);
        }

        dp[n]=0;
        for(int i=n-1;i>=0;i--){
            String cur="";
            int ans=Integer.MAX_VALUE;
            for (int j = i; j < n; j++) {
                cur+=pi[j];
                if(exists.getOrDefault(cur,false)){
                    int other=dp[j+1];
                    if(other!=Integer.MAX_VALUE){
                        ans=Integer.min(ans,1+other);
                    }
                }
            }
            dp[i]=ans;
        }

        //空格数=词数-1
        return dp[0]-1;
    }

    //空间压缩不好压缩


}

2023-12-27 15:26:10