面试题:排序数组中绝对值出现的次数

题目描述:

给定一个有序数组, 求它的元素的绝对值个数. 如数组[-3, -1, 0, 0, 2, 3, 5], 返回5.

思路:

这个题,利用Hashset进行顺序遍历,最后返回set的size()就可以,但是时间复杂度是o(n),要优化算法,我们就需要这样一个思路,看到有序数组,我们首先需要想到二分查找或者双指针的方式。

本题中使用双指针,一个在数组头部,一个在数组尾部,然后两个指针朝两个方向向中间夹逼。我们利用双指针所指向的数的加和做判断,那么它们的加和只有三种情况。

因为数组是排好序的,所以

(1)左右加和大于0,说明尾指针指向的数比头指针指向的数要大,此时我们将尾指针向前移动一位,并将计数加1.

(2)左右加和小于0,说明头指针指向的数是负数,且绝对值比尾指针指向的数要大,此时将头指针向后移动一位,并将计数加1.

(3)左右加和等于0,说明头指针指向的数是负数,且绝对值和尾指针指向的数相等,此时我们需要将首尾指针都向中间推进一位,并将计数加1.

(4)另外,当首尾指针相遇的时候,此时已经退出了循环,首尾指针指向同一个数,此时我们的计数需要再加1.

实现:

public int countDistinctAbs(int[] nums){
	if(nums==null||nums.length==0){
		return -1;
	}
	int i=0;
	int j=nums.length-1;
	int count=0;
	while(i<j){
		if(i<nums.length-1&&nums[i]==nums[i+1]){
			i++;
		}
		if(j>1&&nums[j]==nums[j-1]){
			j--;
		}
		if(nums[i]+nums[j]==0){
			i++;
			j--;
			count++;
		}else if(nums[i]+nums[j]>0){
			j--;
			count++;
		}else if(nums[i]+nums[j]<0){
			i++;
			count++;
		}		
	}
	if(i==j){
		count++;
	}
	return count;	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值