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;
    }
};

 

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