一. 簡介
本文記錄力扣網上的邏輯編程題,涉及數組方面的,這里記錄一下 C語言實現和Python實現。
二.?力扣網C語言編程題:三數之和
題目:三數之和
給你一個整數數組 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i != j、i != k 且 j != k ,同時還滿足 nums[i] + nums[j] + nums[k] == 0 。請你返回所有和為 0 且不重復的三元組。
注意:答案中不可以包含重復的三元組。
示例 1:
輸入:nums = [-1,0,1,2,-1,-4]
輸出:[[-1,-1,2],[-1,0,1]]
解釋:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元組是 [-1,0,1] 和 [-1,-1,2] 。
注意,輸出的順序和三元組的順序并不重要。
示例 2:
輸入:nums = [0,1,1]
輸出:[]
解釋:唯一可能的三元組和不為 0 。
示例 3:
輸入:nums = [0,0,0]
輸出:[[0,0,0]]
解釋:唯一可能的三元組和為 0 。
提示:
? ? 3 <= nums.length <= 3000
? ? -105 <= nums[i] <= 105
解題思路:
根據題目要求,數組中找到三個元素之和為0,且不重復的三元組。這里解決不重復的方法就是排序,排序后查重就可以保證不重復。
固定一個元素,使用雙指針,從數組的頭部與尾部進行同時進行查找,查找第二元素和第三個元素。
具體方法:
1. 從小到大進行排序;
2. 遍歷數組,元素去重;
3. 開始從數組首部和尾部開始同時進行,統計三個元素為 0的元素,如果和小于0,則移動左指針。如果大于0則移動右指針。如果等于0則保存數據,然后對左邊指針的元素進行查重,右邊指針的元素進行查重;
C語言實現如下:
#include <stdio.h>//從小到大排序
int compare_data(const void* a, const void* b) {return *(int*)a -*(int*)b;
}/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {if((nums == NULL) || (numsSize <= 0) || (returnSize == NULL) || (returnColumnSizes == NULL)) {return NULL;}*returnSize = 0;int left = 0;int right = 0;int i = 0; //分配返回數組的緩存int** ret_data = (int**)malloc(10*numsSize * sizeof(int*));*returnColumnSizes = (int*)malloc(10*numsSize * sizeof(int));//從小到大排序qsort(nums, numsSize, sizeof(int), compare_data);//遍歷數組(從頭部和尾部同時)for(i = 0; i < (numsSize-2); i++) {//當前元素大于0,那么更不可能存在sum值等于0的數了,結束遍歷if(nums[i] > 0) {break;}//元素去重(當前元素與上一次元素相等,跳過此次計算)if(i > 0 && nums[i] == nums[i-1]) {continue;}left = i+1;right = numsSize-1;//開始查找三數之和while(left < right) {//判斷和的值int sum = nums[i] + nums[left] + nums[right];if(sum == 0) { //分配內存,保存結果ret_data[*returnSize] = (int*)malloc(3 * sizeof(int));ret_data[*returnSize][0] = nums[i];ret_data[*returnSize][1] = nums[left];ret_data[*returnSize][2] = nums[right];(*returnColumnSizes)[*returnSize] = 3; //返回數組當前行的列數為3(*returnSize)++; //三元組的個數//左邊指針的元素進行查重while((left < right) && (nums[left] == nums[++left]));//右邊指針的元素進行查重while((left < right) && (nums[right] == nums[--right]));}else if(sum < 0) { //左指針向右移找大值left++;}else { //右指針向左移找小值right--;} }}return ret_data;
}
Python實現如下:
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:ret = []n = len(nums)#從小到大進行排序,方便去重nums.sort()#遍歷數組元素(從數組的首部和尾部同時進行)#0 ~ n-3for i in range(0, n-2):#如果第一個元素大于0,則不必查找了(后面元素更大)if(nums[i] > 0):break#元素查重(如果當前元素與上一次元素相等,則跳過這次計算)if(i > 0 and nums[i] == nums[i-1]):continueleft = i + 1right = n - 1#查找和為0的三元組while(left < right):sum = nums[i] + nums[left] + nums[right] #和 == 0if(sum == 0):ret.append([nums[i], nums[left], nums[right]])#左右指針的元素查重while(left < right and nums[left] == nums[left+1]):left += 1while(left < right and nums[right] == nums[right-1]):right -= 1left += 1right -= 1#和 < 0,則左指針向右移(說明和小了,需要和增大)elif(sum < 0): left += 1#和 > 0,則右指針向左移(說明和大了,需要和減小)else:right -= 1return ret
第一次寫 Python,是與 C語言有區別。好像寫起來也沒想象中困難,加油!