四年以后的第一次面试


今天终于有了一次面试,尽管结果多半是凉了,但还好有了第一次面试邀请,这也算是对我简历上的内容的一个认可。


今天下午面的是一家外包,毕竟能力差没办法,能有进正规公司的机会肯定就进正规公司了,但即使是外包公司的面试,对我来说也是非常吃力的,如果100%是满分,那我只能给自己打30%。语言基础和框架部分我就不提了,毕竟都是老生常谈的基本能力。这里我分享面试中遇到的几个基础的算法题,希望能对大家有所帮助。


1 .二维数组由0和1组成,求数组里面的特殊字符个数,特殊字符的定义是:一个数是1,它的横行和竖行全是0,这个1就算是特殊字符。 比如: 00001 10000 01000 00100 00010 得出5


这题我当初写了个O(n^3)的,写了跟没写一样,但是也没办法了。但是我到现在也没想到好的思路,哪位会的大哥教我怎么写啊。


随后按照群里大佬的思路,写了一个O(n^2)的:
   public static int findSpecial(int[][] arr){
        int result = 0;
        int[] columnNum = new int[arr.length];
        int[] countPerColumn = new int[arr[0].length];
        for(int i=0;i<arr.length;i++) {
            int num = 0;
            int j = 0 ;
            columnNum[i] = -1;
            for (j = 0; j < arr[0].length; j++) {
                if (arr[i][j] == 1)
                    num++;
            }
            if(num == 1)
                columnNum[i] = j-1;
        }

        for(int i=0;i<arr[0].length;i++) {
            int num = 0;
            for (int j = 0; j < arr.length; j++) {
                if (arr[j][i] == 1)
                    num++;
            }
            countPerColumn[i] = num;
        }

        for(int i=0;i<arr.length;i++) {
            if(columnNum[i] != -1 && countPerColumn[columnNum[i]] == 1)
                result++;
        }
        return result;
    }


思路就是定义两个数组,一个数组columnNum大小是总行数,一个数组countPerColumn大小是总列数。一行一行遍历数组,只有当当前行有且只有一个1时在columnNum[行数]记录这个1的列数,其余为-1;countPerColumn数组记录每个列的1有多少个。最后遍历数组a1,如果不等于-1且查找countPerColumn数组相应的列只有一个1,则result++


2 . 二叉树的中序遍历


很简单的一题,属于每个人都要会的,我是觉得二叉树除了删除难点,知道个大概就好,其他的都要掌握


	public void traverse(){
        traverse(root);
    }

    private void traverse(TreeNode curr){
        if(curr==null)
            return;
        traverse(curr.left);
        System.out.print(curr.value+" ");
        traverse(curr.right);
    }


3.求两个字符串是否相同,这个字符串包含小写字母和<,<代表把前面一个字符删除,求经过<删除过的两个字符串的是否相同


这题我当初想的是压字符到栈里面,然后遇到多少个<就弹出多少个字符,最后用StringBuilder接收处理一下,而且时间复杂度为O(n),其实感觉还行,谁知面试官说只能用一个额外的存储...我就没办法了,谁知道还能怎么优化优化啊?先把我当时的贴出来吧:
    public static boolean compareString(String s1, String s2){
        return dealWithString(s1).equals(dealWithString(s2));
    }

    private static String dealWithString(String str){
        Stack<Character> s = new Stack<Character>();
        StringBuilder sb = new StringBuilder();
        for(int n=0;n<str.length();n++){
            if(str.charAt(n) == '<' && !s.empty())
                s.pop();
            else
                s.push(str.charAt(n));
        }

        while (!s.empty()){
            sb.append(s.pop());
        }

        return sb.toString();
    }


4 .一个二维数组由0和1组成,如果数组里面有两个或多个1横向或纵向相连,就算是一个岛屿,四周被水包围。求其中最大的岛屿面积。


这题我当初想炸了也不会...后来经过提醒用DFS,我有点递归的思路,但还是不会,后来看了在网络上找到的解答,才一下子明白过来,用两个循环来遍历某个方格,从每个方格开始递归调用周围的,来计算它的1的个数,并且新创了一个数组来判断这个方格有没有被执行过。我当时有这个思路,但是怎么也写不出来。


	public static int findMaxIslandArea(int[][] arr){

        boolean[][] seen = new boolean[arr.length][arr[0].length];
        int ans = 0;
        for (int r = 0; r < arr.length; r++) {
            for (int c = 0; c < arr[0].length; c++) {
                ans = Math.max(ans, area(arr, seen, r, c));
            }
        }
        return ans;
    }


    private static int area(int[][] arr, boolean[][] seen, int r , int c) {

        if (r < 0 || r >= arr.length || c < 0 || c >= arr[0].length ||
                seen[r][c] || arr[r][c] == 0)
            return 0;

        seen[r][c] = true;

        return 1 + area(arr,seen, r+1, c) + area(arr,seen, r-1, c)
                + area(arr,seen, r, c+1) + area(arr,seen, r, c-1);
    }


只能说路还很长,还有很多东西要学啊...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值