18th Feb: Bloomberg字符串题延伸

Problems are related to Reverse Words in a String: 


186. Reverse Words in a String II


Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters.


The input string does not contain leading or trailing spaces and the words are always separated by a single space.


For example,
Given s = "the sky is blue",
return "blue is sky the".


Could you do it in-place without allocating extra space?


Thinking: This problem should be solved in O(1) space complexity because the input doesn't consist of multiple spaces or leading or ending spaces. The key idea is similar to the problem of reverse an array problem. Both of them are using multiple 'reverse' method to achieve the target. 


As well as you don't forget the last word in this string array, you will be fine with this problem.


public class Solution {
    private void reverse(char[] s, int begin, int end) {
        while (begin < end) {
            char tmp = s[begin];
            s[begin] = s[end];
            s[end] = tmp;
            begin++;
            end--;
        }
    }
    
    //总体思路:此题思路和Rotate array类似。先翻转所有的,再按进行局部翻转
    
    public void reverseWords(char[] s) {
        if (s == null || s.length < 2) {
            return;
        }
        
        reverse(s, 0, s.length - 1);
        int wordBegin = 0;
        
        for (int i = 0; i < s.length; i++) {
            if (s[i] == ' ') {
                reverse(s, wordBegin, i - 1);
                wordBegin = i + 1;
            }
        }
        
        reverse(s, wordBegin, s.length - 1);
    }
}

189. Rotate Array


Rotate an array of n elements to the right by k steps.


For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].


Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.


[show hint]


Related problem: Reverse Words in a String II


Thinking: This problem is a little tricky. You can first reverse the whole array. Then reverse [0,k - 1] and [k, length - 1]. 


public class Solution {
    private void reverse(int[] input, int low, int high) {
        while (low < high) {
            int tmp = input[high];
            input[high] = input[low];
            input[low] = tmp;
            low++;
            high--;
        }
    }
    
    public void rotate(int[] nums, int k) {
        if (nums == null || nums.length < 2) {
            return;
        }
        
        k = k % nums.length;
        
        reverse(nums, 0, nums.length - 1);
        reverse(nums, k, nums.length - 1);
        reverse(nums, 0, k - 1);
    }
}

O(n). 


Problems are related to Group Anagrams: 


249. Group Shifted Strings


Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence:


"abc" -> "bcd" -> ... -> "xyz"
Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence.


For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], 
A solution is:


[
  ["abc","bcd","xyz"],
  ["az","ba"],
  ["acef"],
  ["a","z"]
]


Thinking: See the code below. The main idea is uniforming all the shifted words to one representative word. Anagram, in the other way, uses sorting as the uniform method. 


public class Solution {
    public List<List<String>> groupStrings(String[] strings) {
        List<List<String>> ans = new ArrayList<List<String>>();
        if (strings == null || strings.length == 0) {
            return ans;
        }
        
        //这题是shifted string,和anagram类似的,都需要找一个代表形式来统一所有形式从而进行判断
        //for shifted string,the distance of the first character and 'a' is the standard distance. 
        //If two words are shifted string, after every character minus the 'standard' distance, they will become identical. (begins with 'a')
        Map<String, List<String>> repreList= new HashMap<String, List<String>>();
        for (String str : strings) {
            String tmpKey = "";
            char[] tmpCharArray = str.toCharArray();
            int distance = tmpCharArray[0] - 'a';
            
            for (char tmp : str.toCharArray()) {
                tmp = (char)(tmp - distance);
                if (tmp < 'a') {
                    tmp += 26;
                }
                
                tmpKey += tmp;
            }
            
            if (repreList.containsKey(tmpKey)) {
                repreList.get(tmpKey).add(str);
            } else {
                List<String> strList = new ArrayList<String>();
                strList.add(str);
                repreList.put(tmpKey, strList);
            }
        }
        
        return new ArrayList<List<String>>(repreList.values());
    }
}


242. Valid Anagram


Given two strings s and t, write a function to determine if t is an anagram of s.


For example,
s = "anagram", t = "nagaram", return true.
s = "rat", t = "car", return false.


Note:
You may assume the string contains only lowercase alphabets.


Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?


Thinking: About the foundation of ASCII and Unicode (UTF-8), please turn to this link: http://blog.csdn.net/firehotest/article/details/56003617

We used sorting as the uniform method in group anagrams problem. But if we used the unicode, it may not be sortable. In this case, we need to the occurence hash map to judge if this two are anagrams. (Every character should appear the same number of times in each words). 


public class Solution {
    public boolean isAnagram(String s, String t) {
        if (s == null || t == null || s.length() == 0 || t.length() == 0) {
            return true;
        }
        
        int[] occurence = new int[256];
        
        for (char tmp : s.toCharArray()) {
            occurence[tmp] += 1;
        }
        
        for (char tmp : t.toCharArray()) {
            occurence[tmp] -= 1;
        }
        
        for (int tmp : occurence) {
            if (tmp != 0) {
                return false;
            }
        }
        
        return true;
    }
}


266. Palindrome Permutation


Given a string, determine if a permutation of the string could form a palindrome.


For example,
"code" -> False, "aab" -> True, "carerac" -> True.


Thinking: the equivalent problem of this problem is whether the constitution of this string can be organized as a palindrome. The main idea is: If this string is odd number length, we must only have one character that appears odd number of times while the other characters appear even number of times. In contrast, if the string is even number length, all the character should appear even number of times. 


public class Solution {
    public boolean canPermutePalindrome(String s) {
        if (s == null || s.length() < 2) {
            return true;
        }
        
        int[] occurence = new int[256];
        
        for (char tmp : s.toCharArray()) {
            occurence[tmp] += 1;
        }
        
        int onlyOdd = 0;
        
        for (int temp : occurence) {
            if (temp % 2 == 1) {
                onlyOdd++;
            }
            
            if (onlyOdd == 2) {
                return false;
            }
        }
        
        if (s.length() % 2 != 0) {//odd number length
            if (onlyOdd == 1) {
                return true;
            } else {
                return false;
            }
        } else {// even number length
            if (onlyOdd == 0) {
                return true;
            } else {
                return false;
            }
        }
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值