1. 解码异或后的数组
简单题,题解:a ^ b ^ b= 0,用结果和原数组在异或一下就可以了。
class Solution {
public:
vector<int> decode(vector<int>& encoded, int first) {
vector <int >ans;
ans.push_back(first);
int n = encoded.size();
for(int i=0;i<n;i++)
ans.push_back(encoded[i]^ans[i]);
return ans;
}
};
2.交换链表中的节点
简单题。首先计算链表长度,然后找到要交换的两个点的值,再找到要交换的两个点,修改他们的val值即可。
class Solution {
public:
int fun(int k,ListNode* head){
while(k!=1){
k--;
head=head->next;
}
return head->val;
}
ListNode* swapNodes(ListNode* head, int k) {
auto p=head;
int n=0;
while(p!=NULL) {
p=p->next;
n++;
}
p = head;
int kk = n-k+1;
int num=1;
int c1 = fun(k,head);
int c2 = fun(kk,head);
bool flag1=0,flag2=0;
while(p!=NULL){
if(num==k) {
p->val=c2;
flag1=1;
if(flag2) break;
}
if(num==kk){
p->val = c1;
flag2=1;
if(flag1) break;
}
p = p->next;
num++;
}
return head;
}
};
3.执行交换操作的最小汉明距离
中档题。思路: 如果0和1,1和2可以交换,那么0 1 2 这三个位置的数可以是一个全排列。所以我们根据可以构建一个无向图,若a和b可以交换,那么a b之间就有一条边。图的每个联通分量都可以进行全排列。对每个联通分量判断有多少个不相等的元素然后累加一下就可以了(也可求相等的最后在减一下)
class Solution {
public:
bool flag[100000+7];
vector<int>ve[100000+7];
vector<int>v;
map<int ,int >mp;
void dfs(int pos){
if(flag[pos]) return ;
v.push_back(pos);
flag[pos]=1;
for(int i=0;i<ve[pos].size();i++){
dfs(ve[pos][i]);
}
}
int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
int n =allowedSwaps.size();
for(int i=0;i<n;i++){
ve[allowedSwaps[i][1]].push_back(allowedSwaps[i][0]);
ve[allowedSwaps[i][0]].push_back(allowedSwaps[i][1]);
}
int ans=0;
mp.clear();
v.clear();
n = source.size();
for(int i=0;i<n;i++){
dfs(i);
int c=v.size();
for(int i=0;i<c;i++) mp[source[v[i]]]++;
for(int i=0;i<c;i++){
if(mp[target[v[i]]]){
ans++;
mp[target[v[i]]]--;
}
}
v.clear();
mp.clear();
}
return n-ans;
}
};
4.完成所有工作的最短时间
困难题。思路:状压dp。jobs的长度为n,我们可以用[0,2^n-1]中的任何一个数来代表jobs的一个子集i。设j是子集i里的一个元素。val[i]代表子集i的总的工作时间。
val[i] = val[i-j]+val[j]
定义状态dp[i][j]表示工作子集为j时,前i个人里边花费的时间最小值。
状态转移方程
int ci = max(dp[i-1][j-s] ,val[s])
dp[i][j] =min(ci)
其中s表示的集合j的子集。
code:
class Solution {
public:
int val[(1<<12)+7];
int dp[13][(1<<12)+7];
int INF=1e9+7;
int minimumTimeRequired(vector<int>& jobs, int k) {
int n=jobs.size();
memset(dp,0,sizeof dp);
memset(val,0,sizeof val);
for(int i=0;i<(1<<n);i++){
int p=i;
int pos=0;
while(p){
val[i]+= (p&1)? jobs[pos]:0;
p>>=1;
pos++;
}
}
for(int i=0;i<(1<<n);i++) dp[1][i] = val[i];
for(int j=2;j<=k;j++){
for(int i=0;i<(1<<n);i++){
int minv = INF;
for(int s=i;s;s=(s-1)&i){
minv = min(minv,max(dp[j-1][i-s],val[s]));
}
dp[j][i] = minv;
}
}
return dp[k][(1<<n)-1];
}
};