两头指针问题

Minimum Size Subarray Sum**

Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn‘t one, return 0 instead.

看着不难,但是本题的实现起来还会遇到许多的困难

方法一:两头指针,首先遍历数组找到第一个和大于等于目标值的位置,如果到最后都没找到,则返回0,如果开始结束在同一位置,则返回1,然后可得到start和结束位置。之后就是两个指针的移动问题。减去nums[start]之后,如果任大于等于s,那么start++,否则start++,end++,因为那个长度的已经有保证了。注意这里加的时候避免end越界问题。由于end到达最后任然需要继续循环,所以不能使用end作为循环结束的条件,这里使用一个变量i作为循环结束的条件。

 1 class Solution(object):
 2     def minSubArrayLen(self, s, nums):
 3         """
 4         :type s: int
 5         :type nums: List[int]
 6         :rtype: int
 7         """
 8         sum = 0
 9         length = len(nums)
10         if length == 0:
11             return 0
12         i = 0
13         for i in range(length):
14             sum += nums[i]
15             if sum >= s:
16                 break
17         else:
18             return 0
19         start = 0
20         end = i
21         while i < length:
22             if start == end:
23                 return 1
24             sum -= nums[start]
25             if sum >= s:
26                 start += 1
27             elif end < length -1:
28                 start += 1
29                 end += 1
30                 sum += nums[end]
31                 i += 1
32             else:
33                 i += 1
34         return end - start + 1
35         

方法二:首先遍历一遍数组,每个位置上的值为前边所有值得累加和。然后对每个位置使用二分来查找最后一个差大于等于s的位置。

 1 class Solution(object):
 2     def minSubArrayLen(self, s, nums):
 3         """
 4         :type s: int
 5         :type nums: List[int]
 6         :rtype: int
 7         """
 8         length = len(nums)
 9         if length == 0:
10             return 0
11
12         for i in range(1,length):
13             nums[i] += nums[i - 1]
14         if nums[length - 1] < s:
15             return 0
16         result = length
17         for i in range(length):
18             """
19             找到以i结尾的最短的满足条件的位置,也就是最后一个累加和小于等于nums[i] - s的位置
20             """
21             if nums[i] < s:
22                 continue
23             j = self.helper(nums,i,nums[i] - s)
24             result = min(result, i - j)
25         return result
26     def helper(self,nums, i, target):
27         start = 0
28         end = i
29         while start + 1 < end:
30             mid = (start + end) // 2
31             if nums[mid] <= target:
32                 start = mid
33             else:
34                 end = mid
35         if nums[end] <= target:
36             return end
37         elif nums[start] <= target:
38             return start
39         else:
40             return -1

时间: 2024-11-05 14:59:53

两头指针问题的相关文章

如何判断单链表是否存在环 &amp; 判断两链表是否相交

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

一个数组中找到满足和为sum的两个数

如果考虑hashmap直接O(n)的速度, 如果不行,就先排序,两头指针很好推理,关键是 a[beg] +a[end]>sum,意思就是说a[end]太大了,最小的数的都不满足,所以排除a[end] 绝知此事要躬行 #include<iostream>#include<algorithm>using namespace std; bool find(int *a,int sum,int len,int &ans1,int &ans2){    int *beg

第5课 C语言指针深入1

1.客户端两种主流的接口模型: #ifndef _SOCKETCLINET_H #endif _SOCKETCLINET_H #ifdef __cplusplus //如果用了C++的编译器,用C语言的规范来引用 extern "C" { #endif //socket客户端环境初始化 int socketclient_init(void** handle); //socket客户端报文发送 int socketclient_send(void* handle, unsigned ch

C提高 3 字符串与二维指针

二维指针三种内存模型图: 统计字符串两头,非空字符的长度 #include <stdio.h>  #include <stdlib.h> #include <string.h> int main() { //统计字符串两头,非空字符的长度 char *p = "  abc   "; int i = 0; int j = strlen(p) - 1; int count = 0; while (isspace(p[i]) && p[i]

C语言07指针高级

01内存四区 接口封装和设计思想引导 接口封装设计思想引导 Sckclient客户端api模型设计 第一套api函数 #ifndef _SCK_CLINT_H_ #define _SCK_CLINT_H_ //函数声明 // 1.client环境初始化 int sckClient_init(void **handle); //5 day // // 2.client发送报文 int sckClient_send(void *handle, unsigned char *data, int dat

C语言 字符串操作两头堵模型

//字符串操作两头堵模型练习 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> //去除字符串中的空格 //const char *pin的解释:const char *pin是用来限制指针pin指向的数据是个常量,不允许在常量中修改, //但是并不限制实参指针指向的数据也必须是一个常量 //这是为了防止传过来的参数pin所指向的数据不可以修改,

c++ vector 指针返回值问题

关于Vector作为函数的返回值,有几点需要说明: 1.首先如果Vector是一个局部的变量,那么返回该Vector的引用是十分危险的,因为在Vector超出作用域的,会自动调用相关的析构函数(~Vector()),如果Vector中存放的是类(ClassName)对象的指针,则不会调用相关的类ClassName析构函数,只会把相关的空间清空(也就是Vector.size()=0),这样会造成内存泄露.但是如果Vector中存放的是类(ClassName)的对象,则会调用相关的类ClassNam

字符串--两头堵模型解析

题目: 有一个字符串开头或结尾含有n个空格("   abcdefgdddd    "),欲去掉前后空格,返回一个新字符串. 1 // 字符串两头堵模型 2 int TrimSpaceStr(char *p, char *buf) 3 { 4 int rv = 0; 5 char *str = p; 6 int i = 0; // 搜索指针变量,从字符串头部开始 7 int j = strlen(str) - 1;// 搜索指针变量,从字符串尾部开始 8 int len = 0; //

C语言提高 (2) 第二天 用指针对字符串进行操作

2 昨日回顾 p++: (把地址转换成整型 加上它所指向的数据的大小 3指针成立条件和间接赋值 条件一:有两个变量 其中至少一个是指针 条件二:建立关联 条件三:间接操作 4间接操作的例子 5间接操作的内存四区图 6 指针做为函数参数的意义 7指针的总结 8字符串-指针和数组名的区别 1.      sizeof 2.      strlen (遇到\0结束 答:指针是指向可变的指针,数组名是一块常量内存地址. 9中午回顾 10字符串内存四区图 11字符串操作 12 C语言中的0 // 0x00