如果仅利用哈希表等信息判重,会造成 O ( n L ) O(nL) O(nL)的复杂度
考虑状态压缩!利用位运算!分别编码ATCG为00,01,10,11!则每个字符串与一个20位的整数一一对应!
class Solution {
public List<String> findRepeatedDnaSequences(String s) {
Map<Integer,Boolean> a = new HashMap<>();
Map<Character,Integer> b = new HashMap<>();
b.put('A',0);b.put('T',1);b.put('C',2);b.put('G',3);
List<String> ans = new ArrayList<>();
int n = s.length();
if(n <= 10)
return ans;
int mask = (1 << 20) - 1;
//取前10个字符
int value = 0;
for(int i = 0;i<10;i++)
{
value = value | (b.get(s.charAt(i)) << (18 - 2*i));
}
a.put(value,false);
for(int i = 1;i<=n - 10;i++)
{
value = (( value << 2 ) | b.get(s.charAt(i + 9))) & mask;
if(!a.containsKey(value))
{
a.put(value,false);
}
else if(!a.get(value)) {
a.put(value, true);
ans.add(s.substring(i,i+10));
}
}
return ans;
}
}
class Solution {
public int rangeBitwiseAnd(int left, int right) {
// long a;
int ans = 0;
for(int i = 0;i <= 30;i++)
{
if(((left >> i) & 1 )== 1)
{
int j;
for(j = i+1;j<=30 && ((left >> j) & 1 )== 1;j++);
if(j<=30)
{
if(((1 << j) | (left & (Integer.MAX_VALUE - ((1 << j) - 1)) ))>right)
ans |= (1 << i);
}
else ans |= (1 << i);
}
}
return ans;
}
}
class Solution {
public int rangeBitwiseAnd(int left, int right) {
int i = 0;
while(left < right)
{
left = left >> 1;
right = right >> 1;
i++;
}
return left << i;
}
}
class Solution {
public int rangeBitwiseAnd(int left, int right) {
int i = 0;
while(left < right)
{
right &= (right - 1);
}
return right;
}
}
public String getPermutation(int n, int k) {
int[] a = new int[n + 1];
for(int i = 1;i<a.length;i++)
{
a[i ] = i ;
}
int count = 1;
while(count < k)
{
int j;
for(j = a.length - 1;j>=2 && a[j - 1] > a[j];j--);
int q;
for(q = a.length - 1;a[q] <= a[j - 1];q--);
int temp = a[q];
a[q] = a[j - 1];
a[j-1] = temp;
int low = j;
int high = a.length - 1;
while(low <= high)
{
int tmp = a[high];
a[high] = a[low];
a[low] = tmp;
low++;
high--;
}
count ++;
}
//count == k
StringBuilder s = new StringBuilder();
for(int i = 1;i<=a.length - 1;i++)
s.append((char)(a[i] + '0'));
return s.toString();
}
public String getPermutation(int n, int k) {
List<Integer> a = new ArrayList<>();
for(int i = 1;i<=n;i++)
{
a.add(i);
}
StringBuilder s = new StringBuilder();
int acc = 0;
for(int i = 1;i<=n;i++) //n步选择
{
int n_fa = 1;
for(int j = 1;j<=(n - i);j++) {
n_fa *= j;
}
for(int j = 1;j<=n - i + 1;j++)
if(acc + n_fa * j >= k)
{
s.append(a.get(j - 1));
a.remove(j - 1);
acc += n_fa * (j - 1);
break;
}
}
return s.toString();
}
class Solution {
public int dfs(int i,int j,int k,int[][][] dp,String s1,String s2)
{
if(dp[i][j][k]!=0)
return dp[i][j][k];
if(k == 1)
{
dp[i][j][k] = s1.charAt(i) == s2.charAt(j) ? 1 : -1;
return dp[i][j][k];
}
if(i + k - 1 >= s1.length() || j + k - 1 >= s2.length())
{
dp[i][j][k] = -1;
return -1;
}
int a = -1;
dp[i][j][k] = -1;
for(int len = 1 ; len <= k - 1;len++)
{
if(dfs(i,j,len,dp,s1,s2) == 1 && dfs(i + len,j + len,k - len,dp,s1,s2) == 1)
{
dp[i][j][k] = 1;
return 1;
}
if(dfs(i,j+k - len ,len,dp,s1,s2) == 1&& dfs(i +len,j,k - len,dp,s1,s2) == 1)
{
dp[i][j][k] = 1;
return 1;
}
}
return -1;
}
public boolean isScramble(String s1, String s2) {
int[][][] dp = new int[30][30][31]; //dp[i][j][k]表明从s_1开始,从s_2开始的字符串,长度为k的字符串是否能经过扰乱还原
// for(int i = 0;i<30;i++)
// for(int j = 0;j<30;j++)
// {
// if(s1.charAt(i) == s2.charAt(j))
// dp[i][j][k] = 1;
// else dp[i][j][k] = -1;
// }
int a = dfs(0,0,s1.length(),dp,s1,s2);
return a == 1;
}
public static void main(String[] args)
{
new Solution().isScramble("ab","aa");
}
}
class Solution {
public int minimumTime(String s) {
int pre = s.charAt(0) == '0'?0 : 1;
int[] suf = new int[s.length()];
int len = s.length();
suf[len - 1] = s.charAt(len - 1) == 0?0 : 1;
for(int i = len - 2;i>=0;i--)
{
if(s.charAt(i) == '0')
suf[i] = suf[i + 1];
else suf[i] = Math.min(suf[i+1]+2,len - i);
}
int ans = suf[0];
for(int i = 0;i<len - 1;i++)
{
ans = Math.min(suf[i + 1]+pre,ans);
pre = s.charAt(i + 1) == '0'?pre:Math.min(pre + 2,i+2);
}
return Math.min(pre,ans);
}
}
class Solution {
public int minimumTime(String s) {
int pre = s.charAt(0) == '0'?0 : 1;
int len = s.length();
int ans = len;
for(int i = 0;i<len - 1;i++)
{
ans = Math.min(pre + len - i - 1,ans);
pre = s.charAt(i + 1) == '0'?pre:Math.min(pre + 2,i+2);
}
return Math.min(pre,ans);
}
}
class Solution {
public long minimumDifference(int[] nums) {
PriorityQueue<Integer> q_min = new PriorityQueue<>();
int n = nums.length / 3;
long[] right = new long[nums.length];
for(int i = nums.length - 1;i>=2 * n ;i--) {
right[n] += (long)nums[i];
q_min.add(nums[i]);
}
for(int i = 2 * n - 1;i>=n;i--)
{
if(nums[i] > q_min.peek())
{
int a = q_min.poll();
q_min.add(nums[i]);
right[3*n - i] = right[3*n - i - 1] - (long)a + (long)nums[i];
}
else right[3*n - i] = right[3*n - i - 1];
}
long left = 0;
PriorityQueue<Integer> q_max = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return -Integer.compare(o1,o2);
}
});
for(int i = 0;i<n;i++)
{
q_max.add(nums[i]);
left += (long)nums[i];
}
long ans = Long.MAX_VALUE;
ans = Math.min(ans,left - right[2*n]);
for(int i = n ;i<=2*n - 1;i++)
{
if(nums[i] < q_max.peek())
{
int a = q_max.poll();
q_max.add(nums[i]);
left = left + (long)nums[i] - (long)a;
}
ans = Math.min(ans,left - right[3*n - i - 1]);
}
return ans;
}
}