LeetCode刷题记录

题1:4Sum

Given an array nums of n integers and an integer target, are there elements abc, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

The solution set must not contain duplicate quadruplets.

Example:

Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

思路分析:

解法一:3sum+1的方法,在原有3sum基础上再加一层循环,去除重复的组合即可,时间复杂度O(n^3)。

(1)整个数组排序,遍历数组0~nums.size()-4,当前位置设为i,第一层循环 。

(2)遍历数组1~nums.size()-3,,当前位置设为j,第二层循环。

(3)在j~nums.size()-1之间,采用low=j+1,high=nums.size()-1,不断寻找目标值。

(4)通过(nums[low]+nums[high])与target-nums[i]-nums[j]的大小调整。前者大,high--;后者大low++

源码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        //解法2:时间复杂度O(n^3),两层遍历加一层
        
        vector<vector<int>> res;
        if(nums.size()<4)   //去除不符合条件的数组
            return res;
        //排序
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-3;i++)
        {
            for(int j=i+1;j<nums.size()-2;j++)
            {
                int sum = target - nums[i]-nums[j];
                int low =j+1,high = nums.size()-1;
                while(low<high)
                {
                    if(sum > (nums[low]+nums[high]))
                    {
                        low++;
                    }
                    else if(sum < (nums[low]+nums[high]))
                    {
                        high--;
                    }
                    else
                    {
                        vector<int> quadruplet(4, 0);
                        quadruplet[0] = nums[i];
                        quadruplet[1] = nums[j];
                        quadruplet[2] = nums[low];
                        quadruplet[3] = nums[high];
                        res.push_back(quadruplet);
                    
                        // Processing the duplicates of number 3
                        while (low < high && nums[low] == quadruplet[2]) ++low;
                    
                        // Processing the duplicates of number 4
                        while (low < high && nums[high] == quadruplet[3]) --high;
                    }
                }// Processing the duplicates of number 2
                while(j + 1 < nums.size() && nums[j + 1] == nums[j]) ++j;
            }
        
            // Processing the duplicates of number 1
            while (i + 1 < nums.size() && nums[i + 1] == nums[i]) ++i;
        }
        return res;
    }
};

 

解法二:两次折半查找思想的循环,low1和high1、low2和high2(仅AC了60%),时间复杂度O(n^2)。

(1)整个数组排序,取两个指标low1=0和high1=nums.size()-1为外层循环的标记,第一层循环 。

(2)在low1~high1之间,设置low2 = low1+1,high2 = high1-1,作为内层循环的标记,第二层循环。

(3)两次循环的调整步骤相同,都是通过与target的比较来调整low1、low2、high1和high2。

问题:在外层循环的时候,不能将整个数组中的全部组合遍历完,所以出现问题。下面放出源码,待修改!

源码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
         //解法1:时间复杂度 O(n^2),AC,60%,需要进一步修改
         vector<vector<int>> res;
        if(nums.size()<4)
            return res;
        sort(nums.begin(),nums.end());
        int cnt=0;
        int pos1 = 0,pos2 = nums.size()-1;
        
        //内部元素为四个时,判断是够符合标准
        if(pos2 - pos1 == 3 )
        {
           if((nums[0]+nums[1]+nums[2]+nums[3]) == target)
           {
               res.push_back(vector<int>{nums[0],nums[1],nums[2],nums[3]});
           }
           
            return res;
        }
        
        //内部元素大于四个,求组合
        while(pos1 < pos2)
        {
            int low = pos1+1,high = pos2-1;
            cnt=0;
            int target2 = target - nums[pos1]-nums[pos2];
                while(low<high)
                {
                    int sum1 =nums[low] + nums[high];
                    if(target2 == sum1)
                    {
                        res.push_back(vector<int>{nums[pos1],nums[low],nums[high],nums[pos2]});
                        low++;high--;
                    }
                    else if(sum1>target2)
                    {
                        high--;
                        cnt++;
                    } 
                    else if(sum1<target2)
                    {
                        low++;
                        cnt--;
                    }
                }
            if(cnt<0)pos1++;
            else if(cnt>=0)pos2--;
            
        }
        return res;
    }
};

题2:Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

思路分析:

解法一:两组有序链表合并,递归此过程,直至链表数目为1。

(1)选择两组链表进行合并,可以按序合并比如1和2,1和3.....,直至1和n,也可1和n,2和n-1.....不断头尾合并(次数较少)。

(2)两组有序链表进行合并即可,详情见数据结构(严蔚敏版本)链表这一节。

源码:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1,ListNode* list2)
    {
        if(list1 == NULL)return list2;
        else if(list2 == NULL)return list1;
        if(list1->val <= list2->val)
        {
            list1->next = mergeTwoLists(list1->next,list2);
            return list1;
        }
        else
        {
            list2->next = mergeTwoLists(list1,list2->next);
            return list2;
        } 
        
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()) return NULL;
        int len = lists.size();
        while(len>1)
        {
            for(int i=0;i<len/2;++i)
            {
                lists[i] = mergeTwoLists(lists[i],lists[len-1-i]);
            }
            len = (len+1)/2;
        }
        return lists.front();
    }
    
};

解法二:取所有链表的首个元素,共n个元素,组成一个堆,建立最小堆,输出根节点。

(1)初始化一个含有n个元素的容器,将每个链表的头节点放入,建立最小堆,输出根节点。

(2)将最小值对应的链表的值换成下一个节点的值,继续输入。

源码:(暂无)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值