I need to figure out if any anagram of the string can be a palindrome or not.
Ideas:
It relies on two observations:
Frequency of every character in the string is even, if length of the string is even.
Frequency of every character in the string is even except for one character, where frequency must be odd if the string length is odd.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
bool sortAsc(char c, char d) { return c<d; }
int main() {
string s;
cin>>s;
sort(s.begin(), s.end(), sortAsc);
int flag = 0;
string::size_type i=0;
//Even - number of characters whose frequencies are even
//Odd - number of characters whose frequencies are even
int even=0, odd=0;
//The number of times the loop runs is size-1
//because of the reason below
while(i<s.size()-1) {
int temp=0;
//checking if the next char is same as current
//if i will be size-1 then s[i+1] will be out of bound
while(s[i]==s[i+1]) {
++temp;
++i;
}
//if the last element has only one occurrence
//then it should be counted as a character with odd occurrence
if(i==s.size()-2) {
//don't increment temp if
//i is the second last element, just skip everything outside
if(s[i]!=s[i+1]) { ++odd; ++i; continue;}
}
++temp;
if(temp%2==0) { ++even; } else { ++odd; }
++i;
}
if(s.size()%2==0 && odd == 0 || s.size()%2 != 0 && odd == 1)
flag=1;
else
flag=0;
//I could have directly echoed them to console
//but its just the way here
if(flag==0)
cout<<"NO";
else
cout<<"YES";
return 0;
}
As you can see the following block is only used once but condition is checked in every iteration.
if(i==s.size()-2) {
if(s[i]!=s[i+1]) { ++odd; ++i; continue;}
}
It just just there because s[i+1]
if i==size
will return error.
Question:
- Is there any way I can loop until the last index and can still check if the last element has any occurrences?
- Can it be done better without the initial sorting?