Leetcode刷题---167

题目: 在一个增序的整数数组里找到两个数,使它们的和为给定值。已知有且只有一对解。
输入: 输入是一个数组(numbers)和一个给定值(target)。输出是两个数的位置,从 1 开始计数。
Input: numbers = [2,7,11,15], target = 9
输出: Output: [1,2]
方法一: 双指针

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int low = 0, high = numbers.size()-1;
        while(low < high){
            int sum = numbers[low] + numbers[high];
            if(sum == target){
                return {low+1, high+1};
            } else if(sum > target){
                --high;
            } else{
                ++low;
            }
        }
        return {-1, -1};
    }
};

复杂度分析
时间复杂度: O(n),其中 n 是数组的长度。两个指针移动的总次数最多为 n 次
空间复杂度: O(1)

方法二: 二分查找

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        for(int i=0; i<numbers.size(); ++i){
            int low = i+1, high = numbers.size()-1;
            while(low <= high){
                int mid = (high - low) / 2 + low;
                if(numbers[mid] == target - numbers[i]){
                    return {i+1, mid+1};
                } else if(numbers[mid] > target - numbers[i]){
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
        return {-1, -1};
    }
};

复杂度分析
时间复杂度: O(nlogn),其中 n 是数组的长度。需要遍历数组一次确定第一个数,时间复杂度为O(n),寻找第二个数使用二分查找,时间复杂度为O(logn),因此总时间复杂度为O(nlogn).
空间复杂度: O(1)

双指针主要用于遍历数组,两个指针指向不同的元素,协同完成任务,也可以延伸至多个数组的多个指针。
1.若两个指针指向同一数组,遍历方向相同且不会相交,则成为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。
2.若两个指针指向同一数组,但是遍历方向相反,则可以用来搜索,待搜索的数组往往是排好序的。

指针与常量

int x;
int *p1 = &x;					// 指针可以被修改,值也可以被修改
const int *p2 = &x;				// 指针可以被修改,值不可以被修改(const int)
int *const p3 = &x;				// 指针不可以被修改(*const),值可以被修改
const int *const p4 = &x;		// 指针不可以被修改,值也不可以被修改

指针函数与函数指针

// addition是指针函数,一个返回类型是指针的函数
int *addition(int a, int b){
	int *sum = new int(a+b);
	return sum;
}
int subtraction(int a, int b){
	return a - b;
}
int operation(int x, int y, int (*func)(int, int)){
	return (*func)(x, y);
}
// minus是函数指针,指向函数的指针
int (*minus)(int, int) = subtraction;
int *m = addition(1, 2);
int n = operation(3, *m, minus);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值