初级算法(二)
1、引言
2、加一
加一的问题本质上就是进制运算,遇到10就加一,如果是999,那变成1000这些。
//执行用时0ms,内存消耗40.1MB
public int[] plusOne(int[] digits){
int length=digits.length;
for (int i = length-1; i >= 0; i--) {
//如果这个末位的数不是9,直接返回
if(digits[i]!=9){
digits[i]++;
return digits;
}else{
//入宫这个数为九就判断
digits[i]=0;
}
}
int[] temp=new int[digits.length+1];
temp[0]=1;
return temp;
}
3、移动零
这个一开始,我的想法是双指针,但是很明显一开始想出来的东西,就不是最优解。
//方法一:实现双指针,指针i指向数组初始元素,
// 指针j指向数组末尾元素。指针指着的元素若为0,就移动i到j里面的所有元素,并将j--;
//执行用时:52ms,内存消耗:42.6MB
public void moveZeroes(int[] nums) {
if(nums == null || nums.length==0)
return;
int i=0;
int j=nums.length-1;
while(i<=j){
if(nums[i]==0){
for (int k = i; k <j ; k++) {
nums[k]=nums[k+1];
}
nums[j]=0;
j--;
continue;
}
i++;
}
}
第二种方法则采用的也是双指针,不过是把非0的往前挪,后面就全是0
//方法二:也是双指针,就是把非0的往前挪,后面全是零,这个比较简单
//执行用时:1ms,内存消耗:42.3MB
public void moveZeroes2(int[] nums) {
if(nums == null || nums.length == 0){
return;
}
int index=0;
for (int i = 0; i < nums.length ; i++) {
if(nums[i]!=0){
nums[index++]=nums[i];
}
}
while(index< nums.length){
nums[index++]=0;
}
}
第三种方法就是指针指的不同元素进行替换
//方法三:j指向元素不同就和i指向的元素替换
//执行时间:1ms,内存消耗:42.8MB
public void moveZeroes3(int[] nums) {
int i = 0;
for (int j = 0; j < nums.length; j++) {
//只要不为0就往前挪
if (nums[j] != 0) {
//i指向的值和j指向的值交换
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
}
}
}
4、两数之和
方法一:很简单就是暴力解决,两个for循环干就完了。
//方法一:暴力解决,两个for循环
//执行用时:60ms,内存消耗:41.3MB
public int[] twoSum(int[] nums, int target) {
int[] a=new int[2];
for (int i = 0; i <nums.length-1 ; i++) {
for(int j=i+1;j< nums.length;j++){
if(target-nums[i] == nums[j]){
a[0]=i;
a[1]=j;
return a;
}
}
}
return a;
}
方法二:使用Java的数据结构,map集合
//方法二:使用HashMap解决
//执行用时:2ms,内存消耗:41MB
public int[] twoSum2(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if(map.get(target-nums[i])!=null){
return new int[]{map.get(target-nums[i]),i};
}
map.put(nums[i],i);
}
return new int[]{0,0};
}