leetcode 1171. Remove Zero Sum Consecutive Nodes from Linked List 前缀和

leetcode 1171. Remove Zero Sum Consecutive Nodes from Linked List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Range
{
public:
    ListNode* left_p;
    ListNode* right_p;
    Range(ListNode* _left,ListNode* _right):left_p(_left),right_p(_right)
    {}
};
class Solution 
{
public:
    ListNode* get_node_by_dist(ListNode* _begin_p, int _dist)
    {
        if(_dist==-1)
        {
            // before head
            return NULL;
        }
        ListNode* p=_begin_p;
        while(_dist--)
        {
            p=p->next;
        }
        return p;
    }
    ListNode* removeZeroSumSublists(ListNode* head) 
    {
        
        ListNode* p=head;
        vector<int> sum_vec;
        sum_vec.push_back(0);
        int sum=0;
        while(p)
        {
            sum+=(p->val);
            sum_vec.push_back(sum);
            p=p->next;
        }
        int len=sum_vec.size()-1;
//        for(int i=0;i<len;++i)
//        {
//        	cout<<sum_vec[i]<<" ";
//        }
//        cout<<endl;

        vector<Range> range_vec;
        int left_i=0;
        while(left_i<len)
        {
            int left_sum=sum_vec[left_i];
            bool found=false;
            for(int right_i=len;right_i>left_i;--right_i)
            {
                int right_sum=sum_vec[right_i];
                if(left_sum==right_sum)
                {
                    // a pair found
                    found=true;
//                    cout<<"a pair found"<<endl;
                    ListNode* left_p=get_node_by_dist(head,left_i-1);
                    ListNode* right_p=get_node_by_dist(head,right_i-1);
                    range_vec.push_back(Range(left_p,right_p));
                    left_i=right_i+1;
                    break;
                }
            }
            if(!found)
            {
            	++left_i;
            }
			 
        }
        int range_cnt=range_vec.size();
        ListNode* new_head=head;
        for(int i=0;i<range_cnt;++i)
        {
            ListNode* left_p=range_vec[i].left_p;
            ListNode* right_p=range_vec[i].right_p;
            if(left_p==NULL)
            {
                new_head=right_p->next;
            }
            else
            {
                left_p->next=right_p->next;
            }
        }
//        cout<<"done"<<endl;
        return new_head;
    }
};

前缀和数组。left_i从左往右,对每个left_i,right_i从右往左,找到最大的sum相同的一段区间,left_i再跳到right_i右边的位置找下一个区间。
注意删去头部几个值的边界条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值