面试题 01.04. 回文排列


题目

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。
回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。
回文串不一定是字典当中的单词。

示例1:

输入:“tactcoa”
输出:true(排列有"tacocat"、“atcocta”,等等)


解题思路

1.使用hashMap统计出现频率

思路

  • 能够是回文的每个字符的出现频率是有规律的,最多只能有一个字符只出现奇数,其他的字符出现次数必须是偶数!
  • 像是:abbba 或者 acbca

  • 使用hashMap进行统计字符出现频率
  • 最后再判断只要有超过一个字符的出现频率为奇数,那么就返回false,否则返回true

代码

public class Test {
    public static void main(String[] args) {
        String string = "aaabbdd";
        System.out.println(solution(string));
    }

    public static boolean solution(String s) {
        if (s.length() == 0){
            return true;
        }
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            if (!map.containsKey(s.charAt(i))) {
                map.put(s.charAt(i), 0);
            }
            map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
        }
        //最多只能有一个为奇数,大于1则返回false
        int flag = 0;
        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            if (entry.getValue() % 2 == 1) {
                flag++;
            }
            if (flag>1){
                return false;
            }
        }
        return true;
    }
}

性能

  • 时间复杂度和空间复杂度都为O(n)
    在这里插入图片描述

1.5也可以使用set判断!

思路

  • 使用set集合去重
  • 因为set的add方法,是有返回值的,如果set中已有重复的元素,那么put失败会返回false,这也是为什么set中为value设一个Object的固定值,而不是null
    看看set的add()方法的源码
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

因为map的put方法如果没有进行覆盖,那么返回的是null
如果出现重复的key,会将之前的old值进行返回
set底层就是用map的Key来保证的元素唯一性
假如先插入一个a进入set,那么其实就保存到map中了**(key是‘a’,值为obj)**
如果再来个a进入set,那么也就相当于put进map,发生key重复,进行覆盖,并将old value也就是obj进行返回
这个时候add方法返回 map.put(e, PRESENT)==null; 即为false。

看看代码

    public boolean solution(String s) {
        Set<Character> set = new HashSet<>();
        for (char ch : s.toCharArray()) {
            if (!set.add(ch)) {
                set.remove(ch);
            }
        }
        return set.size() <= 1;
    }

2.使用栈进行消消乐~

思路

  • 先将字符串编程char[],进行排序
  • 然后先检查栈顶是不是该字符,如果不是那么在看看栈空间是否大于1,如果大于则说明有多个出现次数为奇数的
  • 如果是该字符,则消消乐!将栈中的栈顶元素pop,然后查看下一个字符。
  • 这里要先判断一下是否为空,不然栈为空的时候stack.peek()会报空指针

代码

public class Test {
    public static void main(String[] args) {
        String string = "aaabbdd";
        System.out.println(solution(string));
    }

    public static boolean solution(String s) {
        if (s.length() == 0) {
            return true;
        }
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        Stack<Character> stack = new Stack<>();
        for (char c : chars) {
        //这里要先判断一下是否为空,不然栈为空的时候stack.peek()会报空指针
            if (stack.size() == 0 || stack.peek() != c) {
                if (stack.size() > 1) {
                    return false;
                }
                stack.push(c);
            } else {
                stack.pop();
            }
        }
        if (stack.size() > 1) {
            return false;
        }
        return true;
    }
}

性能
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值