From 2ad00c00e5ba732f36e9e2ff18ca17942f520687 Mon Sep 17 00:00:00 2001 From: carr Date: Fri, 2 Mar 2018 02:06:36 +0800 Subject: [PATCH 1/3] add one more solution 'isPalindromePermutationsBit' to ch1-q4 --- src/chapter1/ch1-q4.js | 42 ++++++++++++++++++++++++++++++++++--- src/chapter1/ch1-q4.spec.js | 38 ++++++++++++++++++++++++++------- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/chapter1/ch1-q4.js b/src/chapter1/ch1-q4.js index ac1b801..c614455 100644 --- a/src/chapter1/ch1-q4.js +++ b/src/chapter1/ch1-q4.js @@ -20,14 +20,50 @@ export function isPalindromePermutationsSet(str) { let chars = new Set(); for (let char of str) { if (char !== ' ') { // ignore spaces - if (chars.has(char)) { - chars.delete(char); + let lchar = char.toLowerCase(); + if (chars.has(lchar)) { + chars.delete(lchar); } else { - chars.add(char); + chars.add(lchar); } } } return chars.size <= 1; } + +/** + * Use a integer which as 32 bits as a series of flags. Convert each coming + * letter (English Alphabet) to lowercase and map it to an integer between 0 and 26, + * see it as the position of bit and toggle this bit. After iteration, check if + * flags has at most one bit that is set to 1. + * + * N = |str| + * Time: O(N) + * Additional space: O(1) + * + * @param {string[]} str String to check as a character array + * @return {boolean} True if input string is a permutation of a palindrome (ignoring spaces), otherwise false + */ + +export function isPalindromePermutationsBit(str) { + if (!str) { + return false; + } + + let flags = 0; + + for (let char of str) { + if (char !== ' ') { + flags ^= (1 << (char.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0))); + } + } + + return (((flags - 1) & flags) === 0); // ex: It should be 32 bits, abuse 4 bits to represent same logic. + // flags: 0110, 0110 - 0001 = 0101, 0101 & 0110 = 0100 + // flags: 0100, 0100 - 0001 = 0011, 0011 & 0100 = 0000 + // flags: 0000, 0 - 1 = -1, 1111 (two's complement) & 0000 = 0000 +} + + diff --git a/src/chapter1/ch1-q4.spec.js b/src/chapter1/ch1-q4.spec.js index 17a53ab..11f10a4 100644 --- a/src/chapter1/ch1-q4.spec.js +++ b/src/chapter1/ch1-q4.spec.js @@ -18,6 +18,7 @@ for (let key in funcs) { [ ' ', ' ', + 'Tact Coa', 'aabb', 'ab a b', ' a b a b ', @@ -25,22 +26,45 @@ for (let key in funcs) { 'sa sadfgsadfgh jk;hjkz;sadfg hjk;dfghjk;' ].forEach(arg => { - it(`returns true for palindromic string: '${arg}'`, function() { - expect(func(arg.split(''))).to.be.true; - }); + if (key === 'isPalindromePermutationsBit') { + if(/^[a-zA-Z\s]+$/.test(arg)) { + + it(`returns true for palindromic string which only contains English alphabet and space: '${arg}'`, function() { + expect(func(arg.split(''))).to.be.true; + }); + } + } else { + + it(`returns true for palindromic string: '${arg}'`, function() { + expect(func(arg.split(''))).to.be.true; + }); + + } }); [ 'abcadef', '1234567890', - 'a b' + 'a b', + 'sg! sG$' ].forEach(arg => { - it(`returns false for non-palindromic string: '${arg}'`, function() { - expect(func(arg.split(''))).to.be.false; - }); + if (key === 'isPalindromePermutationsBit') { + if(/^[a-zA-Z\s]+$/.test(arg)) { + + it(`returns false for palindromic string which only contains English alphabet and space: '${arg}'`, function() { + expect(func(arg.split(''))).to.be.false; + }); + + } + } else { + + it(`returns false for non-palindromic string: '${arg}'`, function() { + expect(func(arg.split(''))).to.be.false; + }); + } }); }); From 695623607e924a750a80a424c7a45a3bce5ef1c9 Mon Sep 17 00:00:00 2001 From: carr Date: Sun, 4 Mar 2018 21:46:08 +0800 Subject: [PATCH 2/3] Add one more solution 'isPalindromePermutationsBit' to ch1-q4 --- src/chapter1/ch1-q4.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chapter1/ch1-q4.js b/src/chapter1/ch1-q4.js index c614455..36d6ff5 100644 --- a/src/chapter1/ch1-q4.js +++ b/src/chapter1/ch1-q4.js @@ -60,7 +60,8 @@ export function isPalindromePermutationsBit(str) { } } - return (((flags - 1) & flags) === 0); // ex: It should be 32 bits, abuse 4 bits to represent same logic. + return (((flags - 1) & flags) === 0); // ex: flags should be 32 bits, + // abuse 4 bits for brief explanation here. // flags: 0110, 0110 - 0001 = 0101, 0101 & 0110 = 0100 // flags: 0100, 0100 - 0001 = 0011, 0011 & 0100 = 0000 // flags: 0000, 0 - 1 = -1, 1111 (two's complement) & 0000 = 0000 From ddec4afb9fe80f4b008aaa715c70dad93771ad71 Mon Sep 17 00:00:00 2001 From: "Carr.z.w" Date: Tue, 6 Mar 2018 17:26:14 +0800 Subject: [PATCH 3/3] Update ch1-q4.js - Correct comment Correct comment. --- src/chapter1/ch1-q4.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/chapter1/ch1-q4.js b/src/chapter1/ch1-q4.js index 36d6ff5..cfeb4fa 100644 --- a/src/chapter1/ch1-q4.js +++ b/src/chapter1/ch1-q4.js @@ -34,7 +34,7 @@ export function isPalindromePermutationsSet(str) { } /** - * Use a integer which as 32 bits as a series of flags. Convert each coming + * Use a Number in binray form as a series of flags. Convert each coming * letter (English Alphabet) to lowercase and map it to an integer between 0 and 26, * see it as the position of bit and toggle this bit. After iteration, check if * flags has at most one bit that is set to 1. @@ -60,8 +60,7 @@ export function isPalindromePermutationsBit(str) { } } - return (((flags - 1) & flags) === 0); // ex: flags should be 32 bits, - // abuse 4 bits for brief explanation here. + return (((flags - 1) & flags) === 0); // Abuse only 4 bits for brief explanation here. // flags: 0110, 0110 - 0001 = 0101, 0101 & 0110 = 0100 // flags: 0100, 0100 - 0001 = 0011, 0011 & 0100 = 0000 // flags: 0000, 0 - 1 = -1, 1111 (two's complement) & 0000 = 0000