所有题目见https://leetcode.com/problemset/all/
题目一:Reverse Integer
32位整数逆序,输出也得保证是32位整数,溢出情况返回0
代码思路:
1、找到整数最大值,根据最大值所有位数开辟数组空间用于存放各位数字,注意留一个空间存放符号位
2、根据正负零数不同情况拆分遍历数字并存入数组,注意对-2147483648,即最小负整数特殊处理,因为2147483648>2147483647
3、逆序字符串向int转注意越界,所以先用long类型接收,判定在int范围内在返回
通过代码:
class Solution {
public int reverse(int x) {
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
int mm = max;
int count = 0;
while(true){
mm = mm / 10;
count++;
if(mm == 0)
break;
}
int[] num = new int[count+1];
int i = 0;
if(x < 0){
if(x == min)
return 0;
num[i++] = 1;
x = (-1) * x;
while(true){
int v = x % 10;
num[i++] = v;
x = x / 10;
if(x == 0)
break;
}
}else if(x > 0){
i++;
while(true){
int v = x % 10;
num[i++] = v;
x = x / 10;
if(x == 0)
break;
}
}else{
return 0;
}
StringBuilder sb = new StringBuilder();
for(int j = 1 ;j<i; j++){
if(j == 1 && num[j] == 0){
continue;
}else{
sb.append(num[j]);
}
}
if(num[0] == 1){
if(((-1) * Long.valueOf(sb.toString().trim())) < (long)min)
return 0;
else
return (-1) * Integer.valueOf(sb.toString().trim());
}else{
if(Long.valueOf(sb.toString().trim()) > (long)max)
return 0;
else
return Integer.valueOf(sb.toString().trim());
}
}
}
代码改进:
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
boolean flag = false;
if(x == 0)
return 0;
if(x < 0){
if(x == Integer.MIN_VALUE)
return 0;
flag = true;
x = (-1) * x;
}
long res = 0;
while(true){
res = res*10 + x%10;
x /= 10;
if(x == 0)
break;
}
if(res > max)
return 0;
if(flag)
return (-1)*(int)res;
return (int)res;
特别注意:类似1025452289,反转后就超过int范围的数。
题目二:Two Sum
一维整数数组,找出所有两元素和等于给定值,注意一个元素只会使用一次
代码思路:
1、暴力搜索
核心代码:
for(int i = 0;i<nums.length-1;i++)
for(int j = i+1;j<nums.length;j++){
if(nums[i] + nums[j] == target)
return new int[]{i, j};
}
时间复杂度O(n^2),空间复杂度O(1)-------显然不能满足OJ要求
代码改进:确保时间复杂度为O(n)
也即只能遍历一遍数组,所以要记录遍历过的索引和值,想到map集合。新元素与集合中存在的元素组合,如果满足要求即返回,牺牲的空间复杂度O(1)---->O(n)
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();
int[] res = new int[2];
for(int i = 0;i<nums.length;i++){
if(m.containsKey(target - nums[i])){
res[1] = i;
res[0] = m.get(target - nums[i]);
break;
}
m.put(nums[i], i);
}
return res;
}
}
代码参考:http://www.cnblogs.com/grandyang/p/4130379.html
题目3:3SUM
给定一维整数数组,找所有3个元素的和等于0,返回能找到的所有组合集合
思路代码参考:http://www.cnblogs.com/grandyang/p/4481576.html
关于思路问题,肯定能做三层循环暴力搜索,但是时间复杂度为O(n^3)肯定通不过。刚刚做过2sum题目,如果把target移到等式左边就是3sum题目要求,只不过是唯一解,所以,如果先选定一个元素,再找剩下两个元素,便是2sum plus。继续下去,先对数组排序是最优的预处理(不知道为什么,但是直觉这是对的,可能是前人的经验,做题多了,知道这样会节省时间,也便没有去证明或尝试其他方法了,况且java中sort()方法时间复杂度为nlog(n))。
友情提示:注意去除重复值
代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i] > 0)
break;
if(i > 0 && nums[i] == nums[i-1])
continue;
int target = 0 - nums[i];
int m = i+1, n = nums.length-1;
while(m < n){
if(nums[m] + nums[n] == target){
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[m]);
list.add(nums[n]);
res.add(list);
while(m < n && nums[m] == nums[m+1]) m++;
while(m < n && nums[n] == nums[n-1]) n--;
m++;
n--;
}else if(nums[m] + nums[n] < target){
m++;
}else{
n--;
}
}
}
return res;
}
}