82删除排序链表中的重复元素 II;86分隔链表-1-2;90子集 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5


示例 2:

输入: 1->1->1->2->3
输出: 2->3

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode *LN=new ListNode(0);
        LN->next=head;
        ListNode *pre=LN,*cur=head,*next=head->next;
        while(cur){
            next=cur->next;
            if(next&&cur->val==next->val){
                while(next&&next->val==cur->val)
                    next=next->next;
                pre->next=next;
                cur=next;
            }
            else{
                pre=cur;
                cur=next;
            }                
        }
        return LN->next;
    }
};

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在左边,大于x 的节点都在右边,等于x的节点在中间。

每个节点的初始相对位置保持不变。

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(!head||!head->next)return head;
        ListNode *leftHead=new ListNode(0),*midHead=new ListNode(0),*rightHead=new ListNode(0);//一左一右一中间
        ListNode *leftTail=leftHead,*midTail=midHead,*rightTail=rightHead,*cur=head;
        while(cur){
            if(cur->val<x)
                leftTail->next=cur,leftTail=cur;
            else if(cur->val>x)
                rightTail->next=cur,rightTail=cur;
            else    
                midTail->next=cur,midTail=cur;
            cur=cur->next;
        }
        if(midHead->next){
            leftTail->next=midHead->next;
            midTail->next=rightHead->next;            
        }
        else
            leftTail->next=rightHead->next;
        rightTail->next=nullptr;
        head=leftHead->next;
        delete leftHead,midHead,rightHead;
        return head;        
    }
};

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(!head||!head->next)return head;
        ListNode *leftHead=new ListNode(0),*rightHead=new ListNode(0);
        ListNode *leftTail=leftHead,*rightTail=rightHead,*cur=head;
        while(cur){
            if(cur->val<x)
                leftTail->next=cur,leftTail=cur;
            else 
                rightTail->next=cur,rightTail=cur;
            cur=cur->next;
        }
        leftTail->next=rightHead->next;
        rightTail->next=nullptr;
        head=leftHead->next;
        delete leftHead,rightHead;
        return head;        
    }
};

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2]
输出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

class Solution {
    vector<vector<int>>res;
    vector<int>path;
    unordered_map<int,int>sel;//记录相同元素个数>=1
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        if(nums.size()==0)return {{}};
        for(int i=0;i<nums.size();++i)
            sel[nums[i]]++;
        helper(sel.begin(),sel.end());
        return res;
    }
    void helper(unordered_map<int,int>::iterator cur,unordered_map<int,int>::iterator end){
        if(cur==end){
            res.push_back(path);
            return;
        }
        auto temp=cur++;
        helper(cur,end);//不选择当前元素
        for(int i=1;i<=temp->second;++i){
            path.push_back(temp->first);//依此选择i个当前元素
            helper(cur,end);            
        }
        for(int i=1;i<=temp->second;++i)
            path.pop_back();//依此撤回选择
    }
};
class Solution {//位运算
/*去除举例子,假设nums={2,2,2}
i的取值只能有:
000
001
011
111
i的第0位置不考虑去重,1则选择0则不选
从第1位置开始考虑,前一个位置为0则当前位置只能0(1就是要去重的情况),前一个位置为1则当前位置可1可0
*/
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        if(nums.size()==0)return {{}};
        sort(nums.begin(),nums.end());
        vector<vector<int>>res;
        int end=1<<nums.size();
        for(int i=0,j;i<end;++i){
            vector<int>path;
            for(j=0;j<nums.size();++j)
                if((i>>j&1)==1){//检查i的第j位置的值
                    if(j>0&&nums[j]==nums[j-1]&&(i>>(j-1)&1)==0)//去重:当前元素和前一个元素相同时,i的第j位置为1并且i的第j-1位置为0时去重
                        break;
                    path.push_back(nums[j]);
                }
            if(j!=nums.size())continue;//去重
            res.push_back(path);
        }
        return res;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章