字节跳动面试编程题

1.字符串全排列

这里仅实现了小写字母,因为逻辑差不多。
采用了两种判断方式,

  • 一种是在同一层使用的,为了防止相同值的元素被重复使用造成浪费
  • 另一种是层与层之间,防止相同位置的元素被重复使用造成错误

所以最外面使用flags数组,长度为字符串的长度;函数内部创建isReapt数组,长度为26。代码如下:

import java.util.ArrayList;
import java.util.List;

public class StringFullPermutation {
    boolean[] flags; //表示下标为i的元素是否被访问
    List<String> res;
    public List<String> permutation(String string){
        int length = string.length();
        flags = new boolean[length];
        for(int i=0;i<length;i++){
            flags[i] = false;
        }
        res = new ArrayList<String>();

        findNextChar(string,"");
        return res;
    }

    /**
     * 寻找当前字符串的下一个字母
     * @param string
     * @param now
     */
    private void findNextChar(String string, String now) {
        int length = string.length();
        if(now.length() == length){ //如果长度够了,说明这是一个全排列
            res.add(now);
            return;
        }

        int[] isRepeat = new int[26];   //看在这一层是否已经有相同的字母被使用过了,有就不用再使用了(0为未被使用)
        for(int i=0;i<length;i++){
            if(!flags[i] && isRepeat[string.charAt(i)-'a']==0){  //假如第i个字母未被使用
                String newString = now+string.substring(i,i+1);
//                System.out.println("now: "+now);
                flags[i] = true;
                isRepeat[string.charAt(i)-'a'] = 1;
                findNextChar(string,newString);
                flags[i] = false;
                //isReapt只是当前这一层,所以不用回溯
            }
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        StringFullPermutation s = new StringFullPermutation();
        List<String> res= s.permutation("aabc");
        for(String ss:res){
            System.out.println(ss);
        }
    }
}

2.螺旋打印数组

这个题起初是我想得简单了,我以为只需要每次对一个元素进行搜索时按照“右下左上”的顺序来就好了。可是后来发现确实不是。
除了按照顺时针方向,同样还需要优先观察与来的方向相同的方向。所以准备如下:

  • 一个direct二维数组存储方向
  • 一个flags二维数组标志是否被访问
  • 递归函数:所需参数 数组、当前元素的行列号、方向

然后按照从来的时候的方向顺时针深度优先遍历即可。

class Solution {
    int[][] direct = {{0,1},{1,0},{0,-1},{-1,0}};   //右下左上
    int[][] flags;  //标志是否被访问,0为未被访问,1为被访问
    List<Integer> res;
    public List<Integer> spiralOrder(int[][] nums) {
        res = new ArrayList<Integer>();
        int nr = nums.length;
        if(nr==0) return res;
        int nc = nums[0].length;
        flags = new int[nr][nc];

        flags[0][0] = 1;
        res.add(nums[0][0]);
        findNext(nums,0,0,0);

        return res;
    }
    private void findNext(int[][] nums, int r, int c,int index) {
        int i=index;	//i表示在direct中的下标
        for(int j=0;j<3;j++){
            int nr = r + direct[i][0];
            int nc = c + direct[i][1];
            if(inArea(nums, nr, nc) && flags[nr][nc]==0){
                flags[nr][nc] = 1;
                res.add(nums[nr][nc]);
                findNext(nums, nr, nc,i);
            }
            i = (i+1)%4;
        }
    }
    private boolean inArea(int[][] nums, int r, int c){
        if(r>=0 && c>=0 && r<nums.length && c<nums[0].length){
            return true;
        }
        return false;
    }
}
发布了60 篇原创文章 · 获赞 6 · 访问量 1224

猜你喜欢

转载自blog.csdn.net/DLC990319/article/details/104918134