java-61-在数组中,数字减去它右边(注意是右边)的数字得到一个数对之差. 求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5,...

思路来自:[url]http://zhedahht.blog.163.com/blog/static/2541117420116135376632/[/url]
写了个java版的



public class GreatestLeftRightDiff {

/**
* Q61.在数组中,数字减去它右边(注意是右边)的数字得到一个数对之差。
* 求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
*/
public static void main(String[] args) {
int[] a={2, 4, 1, 16, 7, 5, 11, 9};
int result=greatestLeftRightDiff01(a);
System.out.println(result);
result=greatestLeftRightDiff02(a);
System.out.println(result);

}
/*引用原文:
* 如果输入一个长度为n的数组numbers,我们先构建一个长度为n-1的辅助数组diff,
* 并且diff[i]等于numbers[i]-numbers[i+1](0<=i<n-1)。
* 如果我们从数组diff中的第i个数字一直累加到第j个数字(j > i),
* 也就是diff[i] + diff[i+1] + … + diff[j]
* = (numbers[i]-numbers[i+1]) + (numbers[i + 1]-numbers[i+2]) + ... + (numbers[j] – numbers[j + 1])
* = numbers[i] – numbers[j + 1]。
* 分析到这里,我们发现原始数组中最大的数对之差(即numbers[i] – numbers[j + 1])
* 其实是辅助数组diff中最大的连续子数组之和。
*/
public static int greatestLeftRightDiff01(int[] a){
if(a==null||a.length<2){
return Integer.MIN_VALUE;//min=1<<31
}
int len=a.length;
int[] diff=new int[len-1];
for(int i=1;i<len;i++){
diff[i-1]=a[i-1]-a[i];
}
return greatestSumOfSubArray(diff);
}

/*
*1.我的理解:从i=2开始遍历,找出i之前的最大元素,记为max,max减去当前元素a[i],如果这个差值比旧差值大,则更新旧差值
*2.引用原文:
*我们定义diff[i]是以数组中第i个数字为减数的所有数对之差的最大值。
* 也就是说对于任意h(h < i),diff[i]≥number[h]-number[i]。diff[i](0≤i<n)的最大值就是整个数组最大的数对之差。
* 假设我们已经求得了diff[i],我们该怎么求得diff[i+1]呢?对于diff[i],肯定存在一个h(h < i),满足number[h]减去number[i]之差是最大的,也就是number[h]应该是number[i]之前的所有数字的最大值。当我们求diff[i+1]的时候,我们需要找到第i+1个数字之前的最大值。
* 第i+1个数字之前的最大值有两种可能:这个最大值可能是第i个数字之前的最大值,也有可能这个最大值就是第i个数字。
* 第i+1个数字之前的最大值肯定是这两者的较大者。
* 我们只要拿第i+1个数字之前的最大值减去number[i+1],就得到了diff[i+1]。
*/
public static int greatestLeftRightDiff02(int[] a){
if(a==null||a.length<2){
return Integer.MIN_VALUE;//min=1<<31
}
int len=a.length;
int max=a[0];
int diff=max-a[1];
for(int i=2;i<len;i++){
if(max<a[i-1]){
max=a[i-1];
}
int newDiff=max-a[i];
if(newDiff>diff){
diff=newDiff;
}
}
return diff;
}


public static int greatestSumOfSubArray(int[] array){
int sum=0;
int max=0;
for(int i=0,len=array.length;i<len;i++){
sum+=array[i];
if(sum<=0){
sum=0;
}else{
if(sum>max){
max=sum;
}
}
}
return max;
}
}

Java中,如果你想要找出数组中两个元素的和等于给定目标值的第一个元素组合,你可以使用哈希表(HashMap)或者双指针(Two Pointers)算法。这里简单介绍两种常见的解决方案: 1. **哈希表法**: - 遍历数组,将每个元素作为键(key),其索引作为值(value)存入哈希表。 - 再次遍历数组,对于每个元素,计算目标值减去它的值,如果这个值已经在哈希表中,那么找到了一对符合条件的元素。 - 时间复杂度通常为O(n)。 ```java import java.util.HashMap; public int[] twoSum(int[] nums, int target) { HashMap<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[]{map.get(complement), i}; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } ``` 2. **双指针法**: - 定义两个指针,一个指向数组开头(left),另一个指向结尾(right)。 - 如果两个指针所指的数字之和小于目标值,移动左指针;如果大于目标值,移动右指针。 - 直到找到满足条件的两个数或者两个指针相遇为止。 - 时间复杂度也为O(n),空间复杂度为O(1)。 ```java public int[] twoSum(int[] nums, int target) { int left = 0; int right = nums.length - 1; while (left < right) { int sum = nums[left] + nums[right]; if (sum == target) { return new int[]{nums[left], nums[right]}; } else if (sum < target) { left++; } else { right--; } } throw new IllegalArgumentException("No two sum solution"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值