指针和双指针作为函数参数

1. 每个变量都有一个地址和初值,初值可以被改变,这个值的类型可以是int,char,double,float等。

2. 指针是变量,指针变量也有地址和初值,只不过指针变量的值是地址类型。

3. 双指针也是变量,也有地址,变量值的类型是地址的地址。

1. 变量作为函数参数:

void var(int a){

a = 3;

int main(void){

int b = 2;

var(b);

printf(“b=%d/n”, b);//b=2,var函数并没有改变b的值,因为在var函数栈中为形参a开辟一个int空间,调用var函数的时候,不过是将b的值2赋值给形参a,接着在栈中又对变量a赋值为3,并没有对b产生影响。等号左边的是变量,右边的才是值。

2. 指针作为函数参数:

void var(int*a){

*a = 3;

int main(void){

int b = 2;

int *p;

p=&b;

var(p);

printf(“b=%d \n”, b);//b=3,var函数改变了b的值,因为在var函数中为形参a开辟了一个四字节的空间,调用var函数的时候,将b的地址作为值赋值给形参a,接着在栈中对*a进行赋值,即对&b地址所对应的变量复制,改变了b的值,因此,想在一个函数中改变函数外面变量的值,需要将这个变量的地址传进来,或者在函数内部return一个值。

} 

3. 双指针作为函数参数:

void var(int **tmp){

*tmp = (int*)malloc(20*sizeof(int));

memset(*tmp, 0, 20*sizeof(int));

int main(void)

int a = 2;

int *p = &a;

var(&p);

free(p);

通过传指针p的地址给var函数,可以改变指针p的值,在var函数中为指针p所指向的变量开辟了空间,p不再指向a,最后在主函数中释放指针p所指向的内存。

<think>我们正在讨论尺取法与双指针算法的区别及应用场景。根据引用内容,双指针算法是一个广义的概念,通常指使用两个指针在数据结构上协同工作以解决问题的算法技巧。而尺取法(也称为滑动窗口)是双指针算法的一种特定形式,主要用于解决连续子区间问题。根据引用[4]:双指针算法适用于解具有单调性的问题。尺取法正是利用这种单调性,通过两个指针(通常称为左指针指针)来定义一个窗口,并根据条件移动这两个指针来更新窗口,从而高效地解决问题。因此,我们可以将尺取法视为双指针算法的一个子类。它们的区别主要体现在应用场景实现方式上:1.双指针算法:广义上包括多种使用两个指针的技巧,如:-左右指针(用于有序数组的两数之、反转数组等)-快慢指针(用于链表中的环检测、寻找中点等)-滑动窗口(即尺取法,用于连续子数组问题)2.尺取法(滑动窗口):特指用于解决连续子区间问题的双指针方法,通常用于满足一定条件的连续子数组/子字符串问题。其核心是维护一个窗口,通过移动左右指针来调整窗口大小,并利用解的单调性避免重复计算。应用场景对比:-双指针算法(广义)的应用场景更广泛,包括但不限于:*有序数组的两数之(左右指针)*链表中的环检测(快慢指针)*归并排序中的合并步骤(两个指针分别遍历两个有序数组)-尺取法(滑动窗口)的典型应用场景:*最小连续子数组长度(其>=目标值)*无重复字符的最长子串*字符串的排列(判断s2是否包含s1的排列)时间复杂度分析(引用[5]):-双指针算法通常可以将时间复杂度从O(n^2)优化到O(n)或O(nlogn),具体取决于问题。-尺取法通常可以在O(n)时间内解决连续子区间问题,因为每个元素最多被左右指针各访问一次。总结:尺取法是双指针算法的一种特定形式,专门用于解决具有单调性的连续子区间问题。而双指针算法是一个更广泛的概念,包含了多种使用两个指针的技巧。下面我们通过两个示例代码来具体说明:示例1:双指针算法(左右指针)——有序数组的两数之```pythondeftwo_sum(nums,target):left,right=0,len(nums)-1whileleft<right:s=nums[left]+nums[right]ifs==target:return[left,right]elifs<target:left+=1else:right-=1return[]```示例2:尺取法(滑动窗口)——无重复字符的最长子串```pythondeflength_of_longest_substring(s):ifnots:return0left=0max_len=0char_set=set()forrightinrange(len(s)):whiles[right]inchar_set:char_set.remove(s[left])left+=1char_set.add(s[right])max_len=max(max_len,right-left+1)returnmax_len```通过以上分析,我们可以清晰地看到尺取法与双指针算法的区别与联系。§§相关问题§§1.双指针算法除了尺取法还有哪些常见类型?2.尺取法在处理连续子区间问题时为什么高效?3.如何判断一个问题是否适合用尺取法解决?4.双指针算法在链表问题中有哪些典型应用?</think>### 尺取法与双指针算法的区别及应用场景分析 #### **核心概念对比** 1. **双指针算法** - **定义**:使用两个指针在数据结构(数组/链表)上协同工作,通过指针的移动优化问题求解的算法范式[^2][^5]。 - **核心思想**:利用指针移动的**单调性**减少无效遍历,将时间复杂度从 $O(n^2)$ 优化至 $O(n)$[^4][^5]。 - **通用性**:适用于多种场景,包括有序数组、链表、子序列问题等。 2. **尺取法(Sliding Window)** - **定义**:双指针算法的一种特殊形式,通过维护一个**连续区间窗口**(左指针 $L$、右指针 $R$)解决问题[^1]。 - **核心思想**:窗口内的解需满足**连续性****单调性**(如子数组随 $R$ 增大而递增)[^4]。 - **专用性**:专为连续区间问题设计,如子数组/子字符串的最值问题。 #### **关键差异** | **特性** | **双指针算法** | **尺取法** | |----------------|-----------------------------------|-------------------------------| | 指针关系 | 可独立移动(如快慢指针、左右指针) | 严格维护连续区间($L$ $R$ 同步移动) | | 适用问题 | 离散或连续问题(链表环检测、有序数组) | **仅连续区间问题**(子数组、无重复子串) | | 单调性要求 | 部分场景需要(如有序数组) | **必须满足单调性**(窗口内状态随 $R$ 单调变化) | | 典型时间复杂度 | $O(n)$ 或 $O(n \log n)$ | $O(n)$(每个元素进出窗口各一次) | #### **应用场景示例** 1. **双指针算法** - **有序数组两数之**(左右指针)[^2]: ```python def two_sum(nums, target): left, right = 0, len(nums)-1 while left < right: s = nums[left] + nums[right] if s == target: return [left, right] elif s < target: left += 1 else: right -= 1 ``` - **链表环检测**(快慢指针)[^5]:快指针每次移动两步,慢指针移动一步。 2. **尺取法** - **最小满足子数组**(连续区间)[^4]: ```python def min_subarray(nums, target): L, R, total = 0, 0, 0 min_len = float('inf') while R < len(nums): total += nums[R] # 扩展右边界 while total >= target: # 满足条件时收缩左边界 min_len = min(min_len, R-L+1) total -= nums[L] L += 1 R += 1 return min_len if min_len != float('inf') else 0 ``` - **无重复字符的最长子串**:维护窗口内字符不重复。 #### **选择依据** - 使用**尺取法**当且仅当: - 问题涉及**连续区间**(子数组/子字符串) - 解具有**单调性**(如:$R$ 右移时窗口增大,$L$ 右移时窗口减小) - 其他场景(如离散数据、链表操作)选择**广义双指针**。 > **数学原理**:尺取法的效率依赖单调性。例如子数组问题中,函数 $f(L,R)=\sum_{i=L}^{R} a_i$ 关于 $R$ 单调递增,当 $R$ 固定时 $f(L,R)$ 关于 $L$ 单调递减[^4][^5]。这保证了指针移动的确定性,避免回溯。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值