1、两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 104 -109 <= nums[i] <= 109 -109 <= target <= 109
只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
注意这种看似简单但不要暴力计算的题,拿一个数组或者哈希表,保存已经计算过的数据
这个题就是拿一个数组或者哈希表,要找target,就用list[nun-target]=index保存
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
a={}
for i,num in enumerate(nums):
if target-num in a.keys():
return [i,a[target-num]]
a[num]=i
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(hashMap.containsKey(target-nums[i])){
return new int[]{i,hashMap.get(target-nums[i])};
}
else{
hashMap.put(nums[i],i);
}
}
return null;
}
}
7、整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
class Solution {
public int reverse(int x) {
long n = 0;
while(x != 0) {
n = n*10 + x%10;
x = x/10;
}
return (int)n==n? (int)n:0;
}
}
以下就是非常偷懒的做法,但是居然还挺快???
def reverse( x: int) -> int:
a=x if x>0 else -x
l=list(str(a))
l.reverse()
if x>0:
ab=int("".join(l))
else:
ab=-1*int("".join(l))
if ab>2147483647 or ab<-2147483648:
return 0
9、回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
示例 4:
输入:x = -101
输出:false
提示:
进阶:你能不将整数转为字符串来解决这个问题吗?
双指针,一个从头一个从尾,写就完了
13、罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3
示例 2:
输入: "IV"
输出: 4
示例 3:
输入: "IX"
输出: 9
示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= s.length <= 15 s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M') 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。 IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。 关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。
我的思路是,罗马数字中只有 IV,IX,XL,XC,CD,CM六中特殊情况,别的是多少加多少就行
所以先计算一个序列中这六种情况,计算完之后从序列中删除
class Solution {
public int romanToInt(String s) {
int r=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='I'&&(i+1)<s.length()&&s.charAt(i+1)=='V'){
r+=4;
i++;
}
else if(s.charAt(i)=='I'&&(i+1)<s.length()&&s.charAt(i+1)=='X'){
r+=9;
i++;
}
else if(s.charAt(i)=='X'&&(i+1)<s.length()&&s.charAt(i+1)=='L'){
r+=40;
i++;
}
else if(s.charAt(i)=='X'&&(i+1)<s.length()&&s.charAt(i+1)=='C'){
r+=90;
i++;
}
else if(s.charAt(i)=='C'&&(i+1)<s.length()&&s.charAt(i+1)=='D'){
r+=400;
i++;
}
else if(s.charAt(i)=='C'&&(i+1)<s.length()&&s.charAt(i+1)=='M'){
r+=900;
i++;
}
else if(s.charAt(i)=='I') r+=1;
else if(s.charAt(i)=='V') r+=5;
else if(s.charAt(i)=='X') r+=10;
else if(s.charAt(i)=='L') r+=50;
else if(s.charAt(i)=='C') r+=100;
else if(s.charAt(i)=='D') r+=500;
else if(s.charAt(i)=='M') r+=1000;
}
return r;
}
}
14、最常公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
0 <= strs.length <= 200 0 <= strs[i].length <= 200 strs[i] 仅由小写英文字母组成
大概有这五种思路, 一般都会采用第四种, 但是耗时太多
1、所求的最长公共前缀子串一定是每个字符串的前缀子串。所以随便选择一个字符串作为标准,把它的前缀串,与其他所有字符串进行判断,看是否是它们所有人的前缀子串。这里的时间性能是O(m*n*m)。
2、列出所有的字符串的前缀子串,将它们合并后排序,找出其中个数为n且最长的子串。时间性能为O(n*m+m*n*log(m*n))
3、纵向扫描:从下标0开始,判断每一个字符串的下标0,判断是否全部相同。直到遇到不全部相同的下标。时间性能为O(n*m)。
4、横向扫描:前两个字符串找公共子串,将其结果和第三个字符串找公共子串……直到最后一个串。时间性能为O(n*m)。
5、借助trie字典树。将这些字符串存储到trie树中。那么trie树的第一个分叉口之前的单分支树的就是所求。
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length==0){
return "";
}
if(strs.length==1){
return strs[0];
}
if(strs[0].length()==0){
return "";
}
String r="";
int p=0;
int min=strs[0].length();
for (String s:strs){
if(s.length()<min){
min=s.length();
}
}
while (true){
if(p>=min){
r=strs[0].substring(0,p);
break;
}
char temp=strs[0].charAt(p);
for(int i=1;i<strs.length;i++){
if(temp==strs[i].charAt(p)){
continue;
}
else {
r=strs[0].substring(0,p);
return r;
}
}
p++;
}
return r;
}
}
20、有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
提示:
1 <= s.length <= 104 s 仅由括号 '()[]{}' 组成
单纯入栈出栈就行了,最简单的一类题目
class Solution {
public boolean match(char a,char b){
if((a=='('&&b==')')||(a==')'&&b=='(')) return true;
if((a=='['&&b==']')||(a==']'&&b=='[')) return true;
if((a=='{'&&b=='}')||(a=='}'&&b=='{')) return true;
return false;
}
public boolean isValid(String s) {
LinkedList<Character> heap=new LinkedList<Character>();
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='{'||s.charAt(i)=='['||s.charAt(i)=='('){
heap.add(s.charAt(i));
}else {
if(heap.size()==0){
return false;
}
char t=heap.getLast();
heap.removeLast();
if(match(s.charAt(i),t)){
continue;
}else {
return false;
}
}
}
if(heap.size()!=0){
return false;
}
return true;
}
}