11. 盛最多水的容器
给定 n 个非负整数 a*1,*a*2,…,*a*n,每个数代表坐标中的一个点 (*i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
解:双指针
class Solution {
public int maxArea(int[] height) {
int start = 0;
int end = height.length-1;
int max = 0;
while(start<end){
int h = Math.min(height[start],height[end]);
max = Math.max(max,h*(end-start));
if(height[start]>height[end]){
end--;
}else{
start++;
}
}
return max;
}
}
12. 整数转罗马数字
解:操作题
class Solution {
public String intToRoman(int num) {
int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder sb = new StringBuilder();
for(int i=0;i<values.length;i++) {
while(num >= values[i]) {
num -= values[i];
sb.append(strs[i]);
}
}
return sb.toString();
}
}
13. 罗马数字转整数
class Solution {
public:
int romanToInt(string s) {
int res=0;
int lastValue=0;
int digit;
for(int i=s.size()-1;i>=0;i--){
switch(s[i]){
case 'I': digit=1; break;
case 'V': digit=5; break;
case 'X': digit=10; break;
case 'L': digit=50; break;
case 'C': digit=100; break;
case 'D': digit=500; break;
case 'M': digit=1000; break;
}
if(digit>=lastValue){
res+=digit;
lastValue=digit;
}
else res-=digit;
}
return res;
}
};
14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
解:取数组中的一个作为前缀,和其他剩余所有匹配。每次都把前缀缩小一位
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++)
while (strs[i].indexOf(prefix) != 0) {
prefix = prefix.substring(0, prefix.length() - 1);
if (prefix.isEmpty()) return "";
}
return prefix;
}
}
15. 三数之和
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
解:先排序,然后固定a,求bc之和为-a的情况,即转化为2数之和的问题,需要注意的是去重。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
if (nums == null || nums.length == 0) return list;
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//去重
if (i >= 1 && nums[i] == nums[i - 1]) {
continue;
}
int start = i + 1;
int end = nums.length - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum < -nums[i]) {
start++;
while(nums[start] == nums[start-1] && start<end){
start++;
}
} else if (sum > -nums[i]) {
end--;
while(nums[end] == nums[end+1] && start<end){
end--;
}
} else {
List<Integer> l = Arrays.asList(nums[i], nums[start], nums[end]);
list.add(l);
start++;
end--;
while(nums[start] == nums[start - 1] && nums[end] == nums[end + 1] && start < end){
start++;
end--;
}
}
}
}
return list;
}
}
16. 最接近的三数之和
解:同三数之和的思想,也是固定一个,然后在后面进行两数的双指针操作
class Solution {
public int threeSumClosest(int[] nums, int target) {
List<List<Integer>> list = new ArrayList<>();
if (nums == null || nums.length == 0) return -1;
Arrays.sort(nums);
int result=0;
int minAbs = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
int start = i + 1;
int end = nums.length - 1;
while (start < end) {
int sum = nums[i] + nums[start] + nums[end];
int abs = Math.abs(sum-target);
if(abs<minAbs){
minAbs = abs;
result = sum;
}
if(sum<target){
++start;
}else{
--end;
}
}
}
return result;
}
}
17. 电话号码的字母组合
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
解:回溯算法,对于29来说,先2里面取一个a,然后下一层取9中的一个w,得到结果,之后回退到2里面的a,再从9中取y,最后9中取完后回退到2,取下一个b。
class Solution {
public List<String> letterCombinations(String digits) {
List<String> result = new ArrayList<>();
if(digits == null ||"".equals(digits.trim())) return result;
Map<Integer,char[]> map = new HashMap<>();
map.put(2,new char[]{'a','b','c'});
map.put(3,new char[]{'e','d','f'});
map.put(4,new char[]{'g','h','i'});
map.put(5,new char[]{'j','k','l'});
map.put(6,new char[]{'m','n','o'});
map.put(7,new char[]{'p','q','r','s'});
map.put(8,new char[]{'t','u','v'});
map.put(9,new char[]{'w','x','y','z'});
char[] chars = digits.toCharArray();
StringBuilder sb = new StringBuilder();
dfs(chars,result,0,sb,map);
return result;
}
private void dfs(char[] chars, List<String> result, int start, StringBuilder sb, Map<Integer,char[]> map) {
if(sb.length() == chars.length){
result.add(sb.toString());
}
for (int i = start; i < chars.length; i++) {
char[] cs = map.get(chars[i]-'0');
for (char c : cs) {
sb.append(c);
dfs17(chars,result,i+1,sb,map);
sb.deleteCharAt(sb.length()-1);
}
}
}
}