目录
罗马数字转整数
解题思路:当前值和下一个值进行比较,如果小的话就做减法,如果是大的值就做加法
class Solution {
public int romanToInt(String s) {
if(s == null || s.length() == 0){
return 0;
}
Map<Character, Integer> map = new HashMap<Character, Integer>();
map.put('I', 1);
map.put('V', 5);
map.put('X', 10);
map.put('L', 50);
map.put('C', 100);
map.put('D', 500);
map.put('M', 1000);
int sum = 0;
char[] chas = s.toCharArray();
for(int i = 0; i < chas.length - 1; i++){
int curValue = map.get(chas[i]);
int nextValue = map.get(chas[i+1]);
if(curValue < nextValue){
sum -= curValue;
}
else{
sum += curValue;
}
}
int lastValue = map.get(chas[chas.length-1]);
sum += lastValue;
return sum;
}
}
三数之和
class Solution {
//对撞指针;注意去掉重复的值
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length <= 2){
return res;
}
Arrays.sort(nums);//先进行排序
for(int i = 0; i <= nums.length - 3; i++){
//去掉重复的内容
if(i == 0 || nums[i] > nums[i-1]){
int j = i + 1;
int k = nums.length - 1;
while(j < k){
if(nums[i] + nums[j] + nums[k] == 0){
List<Integer> element = new ArrayList<Integer>();
element.add(nums[i]);
element.add(nums[j]);
element.add(nums[k]);
j ++;
k --;
res.add(element);
//去掉重复的
while(j < k && nums[j] == nums[j - 1]){
j ++;
}
while(k > j && nums[k] == nums[k+1]){
k --;
}
}
else if(nums[i] + nums[j] + nums[k] > 0){
k --;
}
else{
j ++;
}
}
}
}
return res;
}
}
最接近的三数之和
class Solution {
public int threeSumClosest(int[] nums, int target) {
if(nums == null || nums.length <= 2){
return -1;
}
int resSum = Integer.MAX_VALUE;
Arrays.sort(nums);//先对数组进行排序
for(int i = 0; i <= nums.length - 3; i ++){
if(i == 0 ||(i > 0 && nums[i] != nums[i-1]) ){
int j = i + 1;
int k = nums.length - 1;
while(j < k){
//找到更接近的值
int sum = nums[i] + nums[j] + nums[k];
//System.out.println(sum);
if(resSum == Integer.MAX_VALUE){
resSum = sum;
}
else if(Math.abs(sum - target) < Math.abs(resSum - target)){
resSum = sum;
}
//值更大的话
if(sum > target){
k --;
}
else if(sum < target){
j ++;
}
else{
return sum;//如果有相等的值的话就直接返回最终的结果
}
}
}
}
return resSum;
}
}
首先进行数组排序,时间复杂度为O(nlogn)
在数组nums中,进行遍历,每遍历一个值利用其下标i,形成一个固定值nums[j]
再使用前指针指向start = i + 1处,后指针指向end = nums.length - 1处,也就是结尾处
根据sum = nums[i] + nums[j] + nums[k]的结果,判断sum与目标target的距离,如果更近则更新结果ans
同时判断sum与target的大小关系,因为数组有序,如果sum > target,则k --,如果sum < target 则j++,如果sum == target则说明距离为0直接返回结果。
时间复杂度:
遍历整个过程,固定值为n次,双指针为n次,时间复杂度为O(nlogn) + O(n * n)
其中排序的时间复杂度为O(nlogn)
电话号码的字母组合
class Solution {
private List<String> res = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits == null || digits.length() == 0){
//这里不能直接返回null,因为null和[]是不同的
return res;
}
String[] strs = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
StringBuilder sb = new StringBuilder();
dfs(0, digits, sb, strs);
return res;
}
public void dfs(int index, String digits, StringBuilder sb, String[] strs){
if(index == digits.length()){
res.add(new String(sb.toString()));
return;//这里少了return
}
char c = digits.charAt(index);
char[] candidates = strs[c-'0'].toCharArray();
for(int i = 0; i < candidates.length; i++){
sb.append(candidates[i] + "");
dfs(index+ 1, digits, sb, strs);
sb.deleteCharAt(sb.length() - 1);//删除最后一个字符
}
}
}
四数之和
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length <= 3){
return res;
}
Arrays.sort(nums);//先进行排序
for(int i = 0; i <= nums.length - 4; i++){
//去掉重复的内容
if(i == 0 || nums[i] > nums[i-1]){
for(int j = i + 1; j <= nums.length - 3; j ++){
if(j == i + 1|| nums[j] > nums[j-1]){
int k = j + 1;
int l = nums.length - 1;
while(k < l){
if(nums[i] + nums[j] + nums[k] + nums[l] == target){
List<Integer> element = new ArrayList<Integer>();
element.add(nums[i]);
element.add(nums[j]);
element.add(nums[k]);
element.add(nums[l]);
k ++;
l --;
res.add(element);
//去掉重复的
while(k < l && nums[k] == nums[k-1]){
k ++;
}
while(l > k && nums[l] == nums[l+1]){
k --;
}
}
else if(nums[i] + nums[j] + nums[k] + nums[l] > target){
l --;
}
else{
k ++;
}
}
}
}
}
}
return res;
}
}