数据结构--数组

四数之和 4sum
第十一章 34

给一个包含 n 个数的整数数组 S,在 S 中找到所有使得和为给定整数 target 的四元组(a, b,c,d)。
注意事项:
四元组(a, b, c, d)中,需要满足 a <= b <= c <= d。
答案中不可以包含重复的四元组。
样例:
例如,对于给定的整数数组 S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集合为:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)

解题思路:

想参照之前的一题 3Sum 的解法来解决,结果超时了。换个思路,空间换时间。既然有四个数,那就把前两个数之和和后两个数之和分别当做一个数。现在要求的就是在一个列表中哪两个数的和为特定值。可以先遍历一遍列表,存值和它的下标的键值对,第二遍遍历列表寻找(目标值-当前值)是否在之前的键值对中,如果在就是符合的一组解。

// An highlighted block

class Solution(object):
    def fourSum(self,nums,target):
        if len(nums) < 4:
            return []
        result =set()
        sumsIndexes = {}
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                if nums[i]+nums[j] in sumsIndexes:
                    sumsIndexes[nums[i]+nums[j]].append((i,j))
                else:
                    sumsIndexes[nums[i]+nums[j]]=[(i,j)]
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                sumNeeded = target-(nums[i]+nums[j])
                if sumNeeded in sumsIndexes:
                    for index in sumsIndexes[sumNeeded]:
                        if index[0]>j:
                            result.add(tuple(sorted([nums[i],nums[j],nums[index[0]],nums[index[1]]])))
        result = [list(l) for l in result]
        return result

if __name__ =="__main__":
    a=Solution()
    b=[1,0,-1,0,-2,2]
    c = 0
    print(a.fourSum(b,c))

----2020/3/12

对一维整型数组a的正确说明是 #define SIZE 10 (换行) int a[SIZE];说法是否正确?

正确答案: A
正确
错误
解析: #define SIZE 10
它的作用是指定标识符SIZE 来代替表达式10。

----已知二维数组A[1: 4, 1: 6]采用列序为主序方式存储,每个元素占用4个存储单元,并且A[3,4]的存储地址为1234,元素A[1, 1]的存储地址是()

正确答案: A
1178
1190
1278
1290
解析:a11+(3*4+2)*4=1234。这样就可以得到a11

----以下定义和初始化的两数组a1和a2,那么下列说法正确的是( )。
char a1[]= “program”;
char a2[]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’}
正确答案: D
a1和a2完全相同
a1和a2不同,a1是指针
a1和a2存储单元的数目相同
a1和a2不同,a1的存储单元数目多

解析:sizeof(a1)=8,sizeof(a2)=7,a1存储单元数目多。

----c中,二维数组初始化的方法是:int a[3][3]={{1},{2},{3}};说法是否正确?

正确答案: A
正确
错误
解析:正确的, 最外层的 { … } 会初始化 a[] 即第一维。

----已知数组D的定义是int D[4][8];,现在需要把这个数组作为实参传递给一个函数进行处理。下列说明汇总可以作为对应的形参变量说明的是()。
正确答案: C D
int D[4][]
int *s[8]
int(*s)[8]
int D[][8]

解析:int *s[8]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。
int (*s)[8]; //定义一个数组指针,该指针指向含8个元素的一维数组(数组中每个元素是int型)。

区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。
int * p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int *说明这是一个整型指针数组。
int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。

2020/3/13
----设有一个长度为n的顺序表,要在第i(从1开始)个元素之前(也就是插入元素作为新表的第i个元素),则移动元素个数为( )。
正确答案: A
n-i+1
n-i
n-i-1
i

解析:1 2 3 4 5
n = 5
要在第i=2个元素之前插入
则n-i=3
而实际插入位置为:
1 [ ] 2 3 4 5
所以是n-i+1

----下面哪项不是链表优于数组的特点?
正确答案: D
方便删除
方便插入
长度可变
存储空间小
解析:链表:方便插入和删除,包含数据和指针域,存储空间大。

----假设有60行70列的二维数组 a[1 …60, 1…70 ] 以列序为主序顺序存储,其基地址为10000,每个元素占2个存储单元,那么第32行第58列的元素 a[ 32,58 ] 的存储地址为

正确答案: A
16902
16904
14454
以上答案均不对

解析:
第32行第58列的元素 表示为 a[ 32,58 ] ,但是我们习惯写成a【31】【57】
二维数组可以表示为A【60】【70】 (60行70列)
a[ 31,57 ]
以列序为主: (5760+31) * 2+10000= 16902
以行序为主: (31
70+57)*2 +10000= 14454

----数组A[0…4,-1…-3,5…7]中含有元素的个数()
正确答案: B
55
45
36
16
解析:三维数组,533=45

----2020/3/14

----数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素的公式为()。

正确答案: D
r-f
(n+f-r)% n
n+r-f
(n+r-f)% n

解析:在这里插入图片描述

----数组常用的两种基本操作是( )。
正确答案: C
建立与删除
删除与查找
查找与修改
插入与索引

解析:删除的时间复杂度比较大,链式结构会采用删除。

----在前提:var arr=[1,3,2]下,下面哪个操作会返回一个数组,并且不是arr?
正确答案: C
arr.push(3)
arr.reverse()
[].concat.call(arr,[])
[].sort.call(arr)

解析:1.contact函数的功能是:连接两个或多个数组。将返回连接数组后的副本,不影响原来的数组 2.call函数调用一个对象的一个方法,以另一个对象替换当前对象 3.js中的函数其实是对象,函数名是对函数对象的引用。

----对有序数组{2、11、15、19、30、32、61、72、88、90、96}进行二分查找,则成功找到15需比较()次
正确答案: C
3
4
2
5
解析:C
0 1 2 3 4 5 6 7 8 9 10
2、11、15、19、30、32、61、72、88、90、96
第一次 index=(0+10)/2=5 对应32 ; 比15大 所以下次范围是 0到4
第二次 index=(0+4)/2=2 对应15 找到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值