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

面试题 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)