本题就是个简单的动态规划题目。首先将nums排序,使得相同的数字近邻。
以dp[i]表示包含nums[0~i]的所有元素的排列。那么:
dp[i+1]的计算如下:
1)当nums[i+1]!=nums[i]时,对于dp[i]中的每一个排列,将nums[i+1]插入到第0~i位置,每次插入到一个位置时,得到的新排列时dp[i+1]中的一个排列;
2)当nums[i+1]=nums[i]时,对于dp[i]中每一个排列,将nums[i+1]插入到nums[i]所在位置之后的任意一个位置,这样得到的每一个新排列都是dp[i+1]的一个排列。
思想:当nums[i]和nums[i+1]相同的时候,保证在任意一个排列中,nums[i]总在nums[i+1]的前面,那么就不会出现重复计算排列。也就是说,相同的元素之间的相对位置始终保持不变,那么就不会存在因为相同元素因为相对位置互换而导致了重复,因为相同元素相对位置不变。
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ret;
if(nums.size()==0) return ret;
sort(nums.begin(),nums.end());
vector<int> tmp(1,nums[0]);
ret.push_back(tmp);
int preNum = nums[0];
for(int i=1;i<nums.size();++i)
{
bool flagDuplicate = false;
if(nums[i]==preNum) flagDuplicate = true;
int px = ret.size()-1;
for(int j = 0;j<=px;++j)
{
ret[j].push_back(nums[i]);
int q = ret[j].size()-1;
int k = q-1;
vector<int> vectmp=ret[j];
while(k>=0&&(!flagDuplicate||vectmp[k]!=nums[i]))
{
vectmp[q]=vectmp[k];
vectmp[k]=nums[i];
ret.push_back(vectmp);
--k;
--q;
}
}
preNum = nums[i];
}
return ret;
}