Leetcode刷题
程序员面试金典(持续更新…)
面试题01.01.判定字符是否唯一
原题链接
实现一个算法,确定一个字符串s
的所有字符是否全都不同。
示例1
输入:s = "leetcode"
输出:false
示例2
输入:s = "abc"
输出:true
限制
0 <= len(s) <=100
如果你不使用额外的数据结构,会很加分
我的解答
- 思路:题目本身比较简单,主要是考虑两个限制,第一个字符串长度不超过100,所以可以忽略,第二个题目要求不能使用额外的数据结构,那就是说使用java自带的可以直接判断是否有重复值的数据结构会减分
- 那最粗暴直接的方法当然是遍历两次字符串,所以就先写了个方法1,运行时间是0ms(毕竟字符串很短),内存消耗36.4MB,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
- 之后想到了字典(python经常用)或者类似C语言的struct结构体,在Java中可以用类来实现,但有些麻烦,而且类应该也是一种额外的数据结构,后来又想到直接通过一个boolean数组实现,只需要观察字符对应index的值是否变化,但是index是一个数值,那么只需要找一种将字符与数值对应的方法,我最先想到的就是ascii码,就查了一下,貌似有扩展的ascii码最多支持256字符(实际用到的肯定少得多),于是就直接使用长度为256的boolean数组,代码如下方法2,执行用时: 0 ms,内存消耗: 36.2 MB,时间复杂度为 O ( n ) O(n) O(n)
方法1
class Solution {
public boolean isUnique(String astr) {
for(int i = 0; i < astr.length(); i++){
for(int j = i + 1; j < astr.length(); j++){
if(astr.charAt(i) == astr.charAt(j))
return false;
}
}
return true;
}
}
方法2
class Solution {
public boolean isUnique(String astr) {
int len = astr.length();
int ascii_of_c;
boolean[] flag = new boolean[256];
for(int i = 0; i < len; i++){
ascii_of_c = Integer.valueOf(astr.charAt(i));
if (flag[ascii_of_c] == true)
return false;
flag[ascii_of_c] = true;
}
return true;
}
}
面试题01.02.判定是否互为字符重排
原题链接
- 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:36 MB, 在所有 Java 提交中击败了86.57%的用户
方法
class Solution {
public boolean CheckPermutation(String s1, String s2) {
if(s1.length() == s2.length()){
int length = s1.length();
int ascii_of_c;
int[] s1_list = new int[128];
for (int i = 0; i < length; i++) {
ascii_of_c = Integer.valueOf(s1.charAt(i));
s1_list[ascii_of_c]++;
ascii_of_c = Integer.valueOf(s2.charAt(i));
s1_list[ascii_of_c]--;
}
for (int i = 0; i < s1_list.length; i++) {
if(s1_list[i] != 0){
return false;
}
}
return true;
}
else{
return false;
}
}
}
面试题01.03.URL化
原题链接
- 执行用时:12 ms, 在所有 Java 提交中击败了68.77%的用户
内存消耗:45.8 MB, 在所有 Java 提交中击败了87.01%的用户
class Solution {
public String replaceSpaces(String S, int length) {
int len = S.length();
char[] url = new char[len];
int count = 0;
for (int i = 0; i < length; i++) {
if (S.charAt(i) == ' ') {
url[count++] = '%';
url[count++] = '2';
url[count++] = '0';
}else{
url[count++] = S.charAt(i);
}
}
String string = new String(url);
String re_s = string.substring(0, count);
return re_s;
}
}
面试题01.04.回文排列
原题链接
- 执行用时:36 ms, 在所有 Python3 提交中击败了82.45%的用户
内存消耗:14.8 MB, 在所有 Python3 提交中击败了74.32%的用户
class Solution(object):
def canPermutePalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
char_dict = {}
for c in s:
if c in char_dict:
char_dict.pop(c)
else:
char_dict[c] = 1
if len(char_dict) < 2:
return True
else:
return False
面试题01.05.一次编辑
原题链接
- 执行用时:36 ms, 在所有 Python3 提交中击败了93.29%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了21.84%的用户
class Solution:
def oneEditAway(self, first: str, second: str) -> bool:
wrong_num = False
len_first = len(first)
len_second = len(second)
i = 0
if abs(len_first - len_second) > 1:
return False
elif len_first + len_second < 2:
return True
elif len_first == len_second:
while i < len_first:
if wrong_num and first[i] != second[i]:
return False
elif wrong_num is False and first[i] != second[i]:
wrong_num = True
i += 1
elif len_first > len_second:
while i < len_second:
if wrong_num and first[i+1] != second[i]:
return False
elif wrong_num is False and first[i] != second[i]:
wrong_num = True
i -= 1
i += 1
elif len_first < len_second:
while i < len_first:
if wrong_num and first[i] != second[i+1]:
return False
elif wrong_num is False and first[i] != second[i]:
wrong_num = True
i -= 1
i += 1
return True
面试题01.06.字符串压缩
原题链接
- 执行用时:60 ms, 在所有 Python3 提交中击败了53.00%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了73.00%的用户
class Solution:
def compressString(self, S: str) -> str:
if S == '':
return ''
current_c = ''
current_n = 0
re_s = ''
for c in S:
if c == current_c:
current_n += 1
else:
re_s += current_c
re_s += str(current_n)
current_c = c
current_n = 1
# 去掉开头的0
re_s += current_c
re_s += str(current_n)
re_s = re_s[1:]
if not len(re_s) < len(S):
return S
else:
return re_s
面试题01.07.旋转矩阵
原题链接
- 执行用时:40 ms, 在所有 Python3 提交中击败了61.70%的用户
内存消耗:14.8 MB, 在所有 Python3 提交中击败了71.14%的用户 - 这个题学习了评论区里面@繁星满天的解题方法(自己研究半天也没发现规律,记录一下)
- 正方形矩阵旋转
- 顺时针旋转矩阵:先上下翻转,再按对角线翻转(转置)
- 逆时针旋转矩阵:先按对角线翻转(转置),再上下翻转
- python的一些用法
- 多维数组切片:
matrix[0:3:1]
三个参数含义:[起始位置:终止位置(不包括): 步长]
,其中,省略写法默认从开始到结尾,步长为1。matrix[::-1]
,将二维数组倒序排列(即为上下翻转)
zip(matrix)
将matrix中每个元素打包为元组,zip(*matrix)
将matrix拆分为元素,再将所有元素打包(这里说的可能不是很清楚,所以直接看示例)map(function, iterable, ...)
为迭代器中每个元素使用function函数
- 多维数组切片:
>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> a[::]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> a[:]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> a[::-1]
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]
>>> list(zip( * a)) # 与下方的效果一致
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> list(zip([1,2,3],[4,5,6],[7,8,9])) # 没加*,与上方效果一致,可知*的作用
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> list(zip(a)) # 不加*,直接zip(a)的效果
[([1, 2, 3],), ([4, 5, 6],), ([7, 8, 9],)]
>>> list(map(list, zip(*a)))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]