11、盛最多水的容器
思路:双指针
我们设置双指针,分别指向数组的起点和结尾处,此时我们能够盛的水量=指针位置高度的较小值*指针之间的间距。这时候需要对指针进行移动,不管移动那个,都会导致间距减小。然而我们要得到最大值,所以我们希望让高度变大,所以移动指针的原则是移动两着高度较小者。
class Solution {
public int maxArea(int[] height) {
int left=0,right=height.length-1;
int max=0;
while(left<right){
int area=Math.min(height[left],height[right])*(right-left);
max=Math.max(max,area);
if(height[left]<height[right]){
left++;
}else{
right--;
}
}
return max;
}
}
12、整数转罗马数字
思路:模拟
将核心的数字对应的用符号做记录,然后让所转换的数字从最高的值往下减,要小于的话就去减下一个。
class Solution {
public String intToRoman(int num) {
int[] a={1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] b={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
String s="";
for(int i=0;i<a.length;i++){
while(num>=a[i]){
num-=a[i];
s+=b[i];
}
}
return s;
}
}
13、罗马数字转整数
思路:模拟
上题用到了数组存储,因为我们需要从大到小进行比较。这次的字符已经给出,我们在遍历的过程中,需要找到对应的数字,并且因为有900、400这种特殊的存在,所以在比较过程中,如果遇到当前字符对应的数字比下一个字符对应的数字小,那么需要减去这个数字,否则就进行累加。
class Solution {
public int romanToInt(String s) {
Map<Character,Integer> map=new HashMap<Character,Integer>(){
{
put('I',1);
put('V',5);
put('X',10);
put('L',50);
put('C',100);
put('D',500);
put('M',1000);
}
};
char[] chars=s.toCharArray();
int res=0;
int n=s.length();
for(int i=0;i<n;i++){
if(i+1<n&&map.get(chars[i])<map.get(chars[i+1])){
res-=map.get(chars[i]);
}else{
res+=map.get(chars[i]);
}
}
return res;
}
}
14、最长公共前缀
思路:横向扫描
我们保存前面字符的公共最长公共前缀字符串,将该字符串与后续的字符进行比较,并不断改进。
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs==null||strs.length==0){
return "";
}
String res=strs[0];
for(int i=1;i<strs.length;i++){
while(strs[i].indexOf(res)!=0){
res=res.substring(0,res.length()-1);
}
}
return res;
}
}
15、三数之和
思路:双指针
三数之和,却要用到双指针?没错,就是固定一个数,然后其他两个数用指针进行遍历,前提是先要将这些数字按照从小到大排序。注意过程中,在遇到固定的数字大于0时就没必要再继续了,因为最小的数字都大于0了后面肯定没有合适的配对结果。利用双指针进行遍历时,遇到配对成功的,也需要进行判断跳过那些相同的数字,避免重复。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> list=new ArrayList<>();
if(nums.length<3){
return list;
}
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
//最小的数都大于0了,后面就没必要再找了
if(nums[i]>0){
return list;
}
if(i>0&&nums[i]==nums[i-1]){
continue;
}
int left=i+1;
int right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum<0){
left++;
}else if(sum>0){
right--;
}else{
list.add(Arrays.asList(nums[i],nums[left],nums[right]));
//跳过相等的数字,避免结果重复
while(left<right&&nums[left]==nums[left+1]){
left++;
}
while(left<right&&nums[right]==nums[right-1]){
right--;
}
left++;
right--;
}
}
}
return list;
}
}