欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode刷面试题(面试题01合集)

程序员文章站 2022-06-04 18:29:43
...

面试题 01.01. 判定字符是否唯一

实现一个算法,确定一个字符串 s 的所有字符是否全都不同。

示例 1:

输入: s = “leetcode”
输出: false
示例 2:

输入: s = “abc”
输出: true
限制:

0 <= len(s) <= 100
如果你不使用额外的数据结构,会很加分。

//这种方式时间复杂度最高
public boolean isUniqueOld(String astr) {
    for (int i = 0; i < astr.length(); i++) {
        for (int j = 0; j < i; j++) {
            if (astr.charAt(i) == astr.charAt(j)) {
                return false;
            }
        }
    }
    return true;
}

//快排内部会建数组
public boolean isUniqueSort(String astr) {
    char[] c = astr.toCharArray();
    //这个不是很符合,因为快排会创建新数组
    Arrays.sort(c);
    for (int i = 1; i < c.length; i++) {
        if (c[i] == c[i - 1]) {
            return false;
        }
    }
    return true;
}

//使用两个long类型,128位,可以记录char内的所有可能(位运算)
public boolean isUnique(String astr) {
    long left = 0;
    long right = 0;
    for (int i = 0; i < astr.length(); i++) {
        if (astr.charAt(i) >= 64) {
            if ((left & (1 << (astr.charAt(i) - 64))) != 0) {
                return false;
            }
            left += (1 << (astr.charAt(i) - 64));
        } else {
            if ((right & (1 << astr.charAt(i))) != 0) {
                return false;
            }
            right += (1 << astr.charAt(i));
        }
    }
    return true;
}

面试题 01.02. 判定是否互为字符重排
给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:

输入: s1 = “abc”, s2 = “bca”
输出: true
示例 2:

输入: s1 = “abc”, s2 = “bad”
输出: false
说明:

0 <= len(s1) <= 100
0 <= len(s2) <= 100

public boolean CheckPermutation(String s1, String s2) {
    if (s1.length() != s2.length()) {
        return false;
    }
    int[] nums = new int[128];
    for (int i = 0; i < s1.length(); i++) {
        nums[s1.charAt(i)]++;
    }
    for (int i = 0; i < s2.length(); i++) {
        nums[s2.charAt(i)]--;
        if (nums[s2.charAt(i)] < 0) {
            return false;
        }
    }
    return true;
}	

面试题 01.03. URL化

URL化。编写一种方法,将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。(注:用Java实现的话,请使用字符数组实现,以便直接在数组上操作。)

示例1:

输入:"Mr John Smith ", 13
输出:“Mr%20John%20Smith”
示例2:

输入:" “, 5
输出:”%20%20%20%20%20"
提示:

字符串长度在[0, 500000]范围内。

//我自己的方法,但是不是很符合在字符组上操作
public String replaceSpaces(String S, int length) {
    StringBuilder sb = new StringBuilder();
    char[] chars = S.toCharArray();
    for (int i = 0; i < length; i++) {
        if (chars[i] == ' ') {
            sb.append("%20");
        } else {
            sb.append(chars[i]);
        }
    }
    return sb.toString();
}	

//字符串尾部有足够的空间存放新增字符, 所以就在原数组上进行操作
public String replaceSpaces(String S, int length) {
    char[] chars = S.toCharArray();
	//从后往前操作
    int end = length - 1;
    int nEnd = chars.length - 1;
    while (end >= 0) {
        if (chars[end] == ' ') {
            end--;
            chars[nEnd--] = '0';
            chars[nEnd--] = '2';
            chars[nEnd--] = '%';
        } else {
            chars[nEnd--] = chars[end--];
        }
    }
    return new String(chars, nEnd + 1, chars.length - 1 - nEnd);
}

面试题 01.04. 回文排列

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。
回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。
回文串不一定是字典当中的单词。

示例1:

输入:“tactcoa”
输出:true(排列有"tacocat"、“atcocta”,等等)

//思想就是,字母个数为奇数个的字母,最多只能有一个
public boolean canPermutePalindrome(String s) {
    int[] nums = new int[128];
    char[] chars = s.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        nums[chars[i]] ^= 1;
    }
    int res = 0;
    for (int i = 0; i < nums.length; i++) {
        res += nums[i];
    }
    return res <= 1;
}

面试题 01.05. 一次编辑

字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。

示例 1:

输入:
first = “pale”
second = “ple”
输出: True

示例 2:

输入:
first = “pales”
second = “pal”
输出: False

public boolean oneEditAway(String first, String second) {
    if (first.length() == second.length()) {
        return sameLen(first, second);
    }
    if (first.length() == second.length() + 1) {
        return moreOne(first, second);
    }
    if (second.length() == first.length() + 1) {
        return moreOne(second, first);
    }
    return false;
}

private boolean sameLen(String first, String second) {
    for (int i = 0; i < first.length(); i++) {
        if (first.charAt(i) != second.charAt(i)) {
            for (int j = i + 1; j < first.length(); j++) {
                if (first.charAt(j) != second.charAt(j)) {
                    return false;
                }
            }
            return true;
        }
    }
    return true;
}

private boolean moreOne(String first, String second) {
    for (int i = 0; i < first.length() - 1; i++) {
        if (first.charAt(i) != second.charAt(i)) {
            //找到多余的之后
            for (int j = i + 1; j < first.length(); j++) {
                if (first.charAt(j) != second.charAt(j - 1)) {
                    return false;
                }
            }
            return true;
        }
    }
    //这就是最后一位多余了
    return true;
}

面试题 01.06. 字符串压缩

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:

输入:“aabcccccaaa”
输出:“a2b1c5a3”
示例2:

输入:“abbccd”
输出:“abbccd”
解释:“abbccd"压缩后为"a1b2c2d1”,比原字符串长度更长。
提示:

字符串长度在[0, 50000]范围内。

public String compressString(String S) {
    if (S.length() == 0) {
        return S;
    }
    char[] chars = S.toCharArray();
    char c = chars[0];
    int num = 1;
    StringBuilder sb = new StringBuilder();
    for (int i = 1; i < chars.length; i++) {
        if (chars[i] == c) {
            num++;
        } else {
            sb.append(c);
            sb.append(num);
            c = chars[i];
            num = 1;
        }
    }
    sb.append(c);
    sb.append(num);
    return sb.toString().length() < S.length() ? sb.toString() : S;
}

面试题 01.07. 旋转矩阵

给定一幅由N × N矩阵表示的图像,其中每个像素的大小为4字节,编写一种方法,将图像旋转90度。

不占用额外内存空间能否做到?

示例 1:

给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],

原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:

给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],

原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]

public void rotate(int[][] matrix) {
    int N = matrix.length;
    for (int i = 0; i < N / 2; i++) {
        for (int j = 0; j < (N + 1) / 2; j++) {
            //找到A左上,B右上,C右下,D左下四个点
            // A(i,j)
            // B(j,N - i - 1)
            // C(N - i - 1,N - j - 1)
            // D(N - j - 1,i)
            //先AD交换
            matrix[i][j] = matrix[i][j] + matrix[N - j - 1][i];
            matrix[N - j - 1][i] = matrix[i][j] - matrix[N - j - 1][i];
            matrix[i][j] = matrix[i][j] - matrix[N - j - 1][i];
            //BC交换
            matrix[j][N - i - 1] = matrix[j][N - i - 1] + matrix[N - i - 1][N - j - 1];
            matrix[N - i - 1][N - j - 1] = matrix[j][N - i - 1] - matrix[N - i - 1][N - j - 1];
            matrix[j][N - i - 1] = matrix[j][N - i - 1] - matrix[N - i - 1][N - j - 1];
            //再BD交换
            matrix[j][N - i - 1] = matrix[j][N - i - 1] + matrix[N - j - 1][i];
            matrix[N - j - 1][i] = matrix[j][N - i - 1] - matrix[N - j - 1][i];
            matrix[j][N - i - 1] = matrix[j][N - i - 1] - matrix[N - j - 1][i];

        }
    }
}

//下面方法更好理解
public void rotate(int[][] matrix) {
    int N = matrix.length;
    //上下对折
    for (int i = 0; i < N / 2; i++) {
        for (int j = 0; j < N; j++) {
            matrix[i][j] = matrix[i][j] + matrix[N - i - 1][j];
            matrix[N - i - 1][j] = matrix[i][j] - matrix[N - i - 1][j];
            matrix[i][j] = matrix[i][j] - matrix[N - i - 1][j];


        }
    }
    //右上左下对折
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            matrix[i][j] = matrix[i][j] + matrix[j][i];
            matrix[j][i] = matrix[i][j] - matrix[j][i];
            matrix[i][j] = matrix[i][j] - matrix[j][i];
        }
    }
}

面试题 01.08. 零矩阵

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例 1:

输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:

输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]

public void setZeroes(int[][] matrix) {
    int N = matrix.length;
    if (N == 0) {
        return;
    }
    int M = matrix[0].length;
	//记录一下当前行是否有0 
    boolean[] rowZero = new boolean[N];
	//记录一下当前列是否有0
    boolean[] colZero = new boolean[M];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (matrix[i][j] == 0) {
                rowZero[i] = true;
                colZero[j] = true;
            }
        }
    }
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (rowZero[i] || colZero[j]) {
                matrix[i][j] = 0;
            }
        }
    }
}

面试题 01.09. 字符串轮转

字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

示例1:

输入:s1 = “waterbottle”, s2 = “erbottlewat”
输出:True
示例2:

输入:s1 = “aa”, “aba”
输出:False
提示:

字符串长度在[0, 100000]范围内。
说明:

你能只调用一次检查子串的方法吗?

先开始没看懂旋转的意思,做了几个测试之后明白了,就是前面的挨个往最后移动

public boolean isFlipedString(String s1, String s2) {
    if (s1.length() != s2.length()) {
        return false;
    }
    return (s1 + s1).indexOf(s2) >= 0;
}
相关标签: 算法 leetcode