再更新。
这两天主要在做简单难度的题,等我大致把简单难度的题都过一遍,再去做中等难度的题目。
文章目录
- 8.15
- [66. 加一](https://leetcode-cn.com/problems/plus-one/)
- [69. x 的平方根](https://leetcode-cn.com/problems/sqrtx/)
- [155. 最小栈](https://leetcode-cn.com/problems/min-stack/)
- [168. Excel表列名称](https://leetcode-cn.com/problems/excel-sheet-column-title/)
- [165. 比较版本号](https://leetcode-cn.com/problems/compare-version-numbers/)
- [171. Excel表列序号](https://leetcode-cn.com/problems/excel-sheet-column-number/)
- [172. 阶乘后的零](https://leetcode-cn.com/problems/factorial-trailing-zeroes/)
- [205. 同构字符串](https://leetcode-cn.com/problems/isomorphic-strings/)
- [219. 存在重复元素 II](https://leetcode-cn.com/problems/contains-duplicate-ii/)
- 8.16
- [225. 用队列实现栈](https://leetcode-cn.com/problems/implement-stack-using-queues/)
- [733. 图像渲染](https://leetcode-cn.com/problems/flood-fill/)
- [231. 2的幂](https://leetcode-cn.com/problems/power-of-two/)
- [232. 用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/)
- [235. 二叉搜索树的最近公共祖先](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)
- [242. 有效的字母异位词](https://leetcode-cn.com/problems/valid-anagram/)
- [257. 二叉树的所有路径](https://leetcode-cn.com/problems/binary-tree-paths/)
- [258. 各位相加](https://leetcode-cn.com/problems/add-digits/)
- [263. 丑数](https://leetcode-cn.com/problems/ugly-number/)
- [264. 丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/)
- [290. 单词规律](https://leetcode-cn.com/problems/word-pattern/)
- [292. Nim 游戏](https://leetcode-cn.com/problems/nim-game/)
- [299. 猜数字游戏](https://leetcode-cn.com/problems/bulls-and-cows/)
- [326. 3的幂](https://leetcode-cn.com/problems/power-of-three/)
- [342. 4的幂](https://leetcode-cn.com/problems/power-of-four/)
- [345. 反转字符串中的元音字母](https://leetcode-cn.com/problems/reverse-vowels-of-a-string/)
- [367. 有效的完全平方数](https://leetcode-cn.com/problems/valid-perfect-square/)
- [383. 赎金信](https://leetcode-cn.com/problems/ransom-note/)
- [387. 字符串中的第一个唯一字符](https://leetcode-cn.com/problems/first-unique-character-in-a-string/)
- [389. 找不同](https://leetcode-cn.com/problems/find-the-difference/)
8.15
66. 加一
难度简单
用之前类似字符串相加的方法做的。这样的话是用了额外空间,而且链表和数组的赋值替换比较费时间。
class Solution {
public int[] plusOne(int[] digits) {
if(digits.length == 0){
return new int[]{1};
}
int carry = 1;
int index = digits.length - 1;
List<Integer> list = new ArrayList<>();
while(index >= 0 || carry > 0){
int val = index >= 0 ? digits[index] : 0;
int sum = val + carry;
list.add(sum % 10);
carry = sum / 10;
index--;
}
int[] ans = new int[list.size()];
for(int i = 0;i < ans.length;i++){
ans[i] = list.get(ans.length - i - 1);
}
return ans;
}
}
然后写了一种原地修改的写法,不过原地修改的前提是数组长度不变,如果加一之后数组长度变长,那么就只能再重新开辟一个新的数组。
class Solution {
public int[] plusOne(int[] digits) {
if(digits.length == 0){
return new int[]{1};
}
int carry = 1;
int index = digits.length - 1;
while(index >= 0){
digits[index] += carry;
if(digits[index] >= 10){
carry = digits[index] / 10;
digits[index] %= 10;
index--;
}else{
carry = 0;
return digits;
}
}
if(carry > 0){
int[] ans = new int[digits.length + 1];
ans[0] = carry;
System.arraycopy(digits, 0, ans, 1, digits.length);
return ans;
}
return null;//正常来说是无法到达的
}
}
69. x 的平方根
难度简单
本来是直接调用了Math.sqrt()函数直接解决的。不过不能偷懒了,就改用了二分查找的算法来实现。
class Solution {
public int mySqrt(int x) {
int begin = 0;
int end = x;
int ans = 0;
while(begin <= end){
int mid = begin + (end - begin) / 2;
if((long)mid * mid <= x){
ans = mid;
begin = mid + 1;
}else{
end = mid - 1;
}
}
return ans;
}
}
155. 最小栈
难度简单
也算是比较经典的题目了,用两个栈来实现
class MinStack {
Stack<Integer> myStack;
Stack<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
myStack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
if(minStack.isEmpty() || minStack.peek() >= x){
minStack.push(x);
}else if(minStack.peek() <= x){
minStack.push(minStack.peek());
}
myStack.push(x);
}
public void pop() {
myStack.pop();
minStack.pop();
}
public int top() {
return myStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
168. Excel表列名称
难度简单
实际上就是一个进制的转换,需要注意的是它是从1 - 26,而不是0 - 25.所以为了能够正常的表示,我们有一步特殊操作(c == 0)
class Solution {
//实际上就是把十进制的数变为二十六进制
public String convertToTitle(int n) {
StringBuilder sb = new StringBuilder();
while (n > 0) {
int c = n % 26;
if(c == 0){
c = 26;
n -= 1;//之后的n / 26 是可以整除的,但是按照列的转换规则,他应该取比他小的下一个整数,所以让n--
}
sb.insert(0, (char) ('A' + c - 1));
n /= 26;
}
return sb.toString();
}
}
165. 比较版本号
难度中等
主要思想就是先将字符串进行分割,之后再根据得到的字符串数组进行对比判断。
尤其需要注意的一点是String的分割时用的是"//.“而不是”."。这个问题很关键。
class Solution {
public boolean isEqualsZero(int index, String[] v){
for(int i = index;i < v.length;i++){
if(Integer.parseInt(v[i]) != 0){
return false;
}
}
return true;
}
public int compareVersion(String version1, String version2) {
String[] v1 = version1.split("\\.");
String[] v2 = version2.split("\\.");
int index1 = 0;
int index2 = 0;
while(index1 < v1.length || index2 < v2.length){
if(index1 == v1.length){
if(isEqualsZero(index2, v2)){
break;
}
return -1;
}else if(index2 == v2.length){
if(isEqualsZero(index1, v1)){
break;
}
return 1;
}
int val1 = Integer.parseInt(v1[index1]);
int val2 = Integer.parseInt(v2[index2]);
if(val1 > val2){
return 1;
}else if(val1 < val2){
return -1;
}
index1++;
index2++;
}
return 0;
}
}
171. Excel表列序号
难度简单
二十六进制转变成十进制即可。
class Solution {
public int titleToNumber(String s) {
char[] arr = s.toCharArray();
int ans = 0;
int len = arr.length;
for(int i = 0;i < len;i++){
int num = arr[i] - 'A' + 1;
ans += (int)Math.pow(26, len - i - 1) * num;
}
return ans;
}
}
172. 阶乘后的零
难度简单
为了得到后面的0,我们可以注意到,阶乘如果后面会出现零,那么只可能是2 * 5的情况,所以我们只需要去计算其中2的个数和5的个数就行。但是再想一想,我们发现2的出现频率一定比5要高,所以我们实际上计算出5的个数就能得出阶乘后零的个数。
class Solution {
//要出现0,那么就要计算其中的2的个数和5的个数(2的个数一定大于5的个数,所以实质上只需要去找到其中拥有的5的个数就可以了)
public int trailingZeroes(int n) {
int zeroCount = 0;
for(int i = 5;i <= n;i += 5){
int temp = i;
while(temp % 5 == 0){//累加上5的个数
zeroCount++;
temp /= 5;
}
}
return zeroCount;
}
}
205. 同构字符串
难度简单
ascii码总共有128位,所以用128长度的数组来标识前一个字符出现的位置。首先需要把数组都初始化为-1,以免造成映射到第0位的错误。
class Solution {
public boolean isIsomorphic(String s, String t) {
if(s.length() != t.length()){
return false;
}
int[] count1 = new int[128];
int[] count2 = new int[128];
Arrays.fill(count1, -1);
Arrays.fill(count2, -1);
for(int i = 0;i < s.length();i++){
char a = s.charAt(i);
char b = t.charAt(i);
if(count1[a] == count2[b]){
count1[a] = i;
count2[b] = i;
}else{
return false;
}
}
return true;
}
}
219. 存在重复元素 II
难度简单
暴力求解
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
for(int i = 0;i < nums.length;i++){
for(int j = i + 1;j <= i + k && j < nums.length;j++){
if(nums[i] == nums[j]){
return true;
}
}
}
return false;
}
}
还有就是借助一个set来辅助存取(有点像一个无序的窗口)。
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new HashSet<>();
for(int i = 0;i < nums.length;i++){
if(set.contains(nums[i])){
return true;
}
set.add(nums[i]);
if(set.size() > k){
set.remove(nums[i - k]);
}
}
return false;
}
}
8.16
225. 用队列实现栈
难度简单
也算是比较经典的题目了,最开始把队列的性质想错了,所以做错了。
实际上我们只需要借助两个队列,交替元素位置,找到队列的最后一个元素就是弹出的值。
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
/** Initialize your data structure here. */
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
while(!queue2.isEmpty()){
queue1.offer(queue2.poll());
}
queue1.offer(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int val = -1;
if(!queue1.isEmpty()){
while(!queue1.isEmpty()){
if(queue1.size() == 1){
val = queue1.poll();
}else{
queue2.offer(queue1.poll());
}
}
}else{
while(!queue2.isEmpty()){
if(queue2.size() == 1){
val = queue2.poll();
}else{
queue1.offer(queue2.poll());
}
}
}
return val;
}
/** Get the top element. */
public int top() {
int val = -1;
if(!queue1.isEmpty()){
while(!queue1.isEmpty()){
if(queue1.size() == 1){
val = queue1.peek();
}
queue2.offer(queue1.poll());
}
}else{
while(!queue2.isEmpty()){
if(queue2.size() == 1){
val = queue2.peek();
}
queue1.offer(queue2.poll());
}
}
return val;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.isEmpty() && queue2.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
733. 图像渲染
难度简单
就是一个简单的深度优先遍历,其中需要注意的点是oldColor和newColor相同的情况,这时可以直接退出。
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
if(image.length == 0){
return new int[0][];
}
dfs(image, sr, sc, image[sr][sc], newColor);
return image;
}
public void dfs(int[][] image, int i, int j, int oldColor, int newColor){
if(oldColor == newColor){
return ;
}
if(i >= 0 && i < image.length && j >=0 && j < image[0].length && image[i][j] == oldColor){
image[i][j] = newColor;
dfs(image, i + 1, j, oldColor, newColor);
dfs(image, i - 1, j, oldColor, newColor);
dfs(image, i, j + 1, oldColor, newColor);
dfs(image, i, j - 1, oldColor, newColor);
}
}
}
231. 2的幂
难度简单
比较简单的题越需要注意。这里输入的整数可能是非正数,这时可以直接返回false。
class Solution {
public boolean isPowerOfTwo(int n) {
if(n <= 0){
return false;
}
while(n > 1){
if(n % 2 != 0){
return false;
}
n = n >> 1;
}
return true;
}
}
232. 用栈实现队列
难度简单
这个题也是比较经典的题目
class MyQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
/** Initialize your data structure here. */
public MyQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
while(!stack2.isEmpty()){
stack1.push(stack2.pop());
}
stack1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
/** Get the front element. */
public int peek() {
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
return stack2.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stack1.isEmpty() && stack2.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
235. 二叉搜索树的最近公共祖先
难度简单
之前做过类似的题目。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == q || root == p){
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left == null){
return right;
}else if(right == null){
return left;
}else{
return root;
}
}
}
上面的做法是通用的解法,如果树是BST,那么我们就可以利用BST的性质来优化算法。
如果p、q节点的值都比root的值要小,则最近公共祖先一定在root的左子树上。如果都要更大,那么最近公共祖先一定在root的右子数上。不然的话root就是他们最近的公共祖先。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == q || root == p){
return root;
}
int val = root.val;
int val1 = p.val;
int val2 = q.val;
if(val > val1 && val > val2){
return lowestCommonAncestor(root.left, p, q);
}else if(val < val1 && val < val2){
return lowestCommonAncestor(root.right, p, q);
}else{
return root;
}
}
}
242. 有效的字母异位词
难度简单
通用的解法是利用哈希表。如果使用哈希表的话,需要注意的一点是关于Integer的相等判断,如果字符串足够长,关于Integer的相等判断就不能利用来进行判断(因为Integer是一个引用对象,在值小于128时,内部的比较是利用int值来比较的。如果值大于等于128,那么比较的就是两者的引用是否相同)。
class Solution {
public boolean isAnagram(String s, String t) {
Map<Character, Integer> map1 = getCharMap(s);
Map<Character, Integer> map2 = getCharMap(t);
if(map1.size() != map2.size()){
return false;
}
for(Map.Entry<Character, Integer> entry : map1.entrySet()){
if(!map2.containsKey(entry.getKey()) ||
!map2.get(entry.getKey()).equals(entry.getValue())){
return false;
}
}
return true;
}
public Map<Character, Integer> getCharMap(String str){
Map<Character, Integer> map = new HashMap<>();
for(char c : str.toCharArray()){
if(map.containsKey(c)){
map.put(c, map.get(c) + 1);
}else{
map.put(c, 1);
}
}
return map;
}
}
如果只包含ascii字符的话,可以将哈希表简化成一个长度128得到数组,分别遍历两个字符串,看数组最后是不是全为0即可。
257. 二叉树的所有路径
难度简单
深度优先遍历,利用一个list来辅助存储遍历到的值。当退出当前遍历时,把本次加入的值去掉。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> ans = new LinkedList<>();
if(root == null){
return ans;
}
dfs(root, ans, new LinkedList<String>());
return ans;
}
public void dfs(TreeNode root, List<String> ans, List<String> path){
path.add(String.valueOf(root.val));
if(root.left == null && root.right == null){
StringBuilder sb = new StringBuilder();
for(String str : path){
sb.append(str).append("->");
}
ans.add(sb.toString().substring(0, sb.length() - 2));
}else{
if(root.left != null){
dfs(root.left, ans, path);
}
if(root.right != null){
dfs(root.right, ans, path);
}
}
path.remove(path.size() - 1);
}
}
258. 各位相加
难度简单
一个简单的数字的各位处理。
class Solution {
public int addDigits(int num) {
while(num / 10 != 0){
int temp = 0;
while(num > 0){
temp += num % 10;
num /= 10;
}
num = temp;
}
return num;
}
}
263. 丑数
难度简单
暴力解决。
class Solution {
public boolean isUgly(int num) {
if(num < 1){
return false;
}
while(num > 5){
if(num % 2 == 0){
num /= 2;
}else if(num % 3 == 0){
num /= 3;
}else if(num % 5 == 0){
num /= 5;
}else{
return false;
}
}
return true;
}
}
264. 丑数 II
难度中等
借助了一个set来辅助判断是否是丑数,但是最后超时了。
超时的可能大概是因为我是按照顺序去找丑数,每个数都进行了判断,花费了太多时间。换种想法,根据之前的丑数计算出下一个丑数,这样就能跳过很多数字。
class Solution {
public int nthUglyNumber(int n) {
if(n < 1){
return -1;
}
Set<Integer> set = new HashSet<>();
for(int i = 1;i <= 5;i++){
set.add(i);
if(set.size() == n){
return i;
}
}
for(int i = 6;set.size() < n;i++){
if((i % 2 == 0 && set.contains(i / 2)) || (i % 3 == 0 && set.contains(i / 3)) || (i % 5 == 0 && set.contains(i / 5))){
set.add(i);
if(set.size() == n){
return i;
}
}
}
return -1;
}
}
其中需要注意的点是更新三个指针。只要满足要求就需要更新,而不是只更新满足条件的一个。不然会出现重复的数字。
class Solution {
public int nthUglyNumber(int n) {
if(n < 1){
return -1;
}
int[] dp = new int[1690];
int i2 = 0;
int i3 = 0;
int i5 = 0;
dp[0] = 1;
int ugly;
for(int i = 1;i < 1690;i++){
ugly = Math.min(Math.min(dp[i2] * 2, dp[i3] * 3), dp[i5] * 5);
dp[i] = ugly;
if(ugly == dp[i2] * 2){
i2++;
}
if(ugly == dp[i3] * 3){
i3++;
}
if(ugly == dp[i5] * 5){
i5++;
}
}
return dp[n - 1];
}
}
290. 单词规律
难度简单
说实话,这个题应该没那么难,但是自己实现的时候还是有点困难。
其中需要注意的点是pattern和str切分后的数组长度不一致,和同一个字符串映射到了不同的字符上。只要注意这两个地方,那问题应该不大。
class Solution {
public boolean wordPattern(String pattern, String str) {
String[] arr = str.split(" ");
if(arr.length != pattern.length()){
return false;
}
int[] count = new int[26];
Arrays.fill(count, -1);
Map<String, Character> map = new HashMap<>();
int i = 0;
for(char c : pattern.toCharArray()){
int index = count[c - 'a'];
if(index != -1){
if(!arr[index].equals(arr[i]) || !map.get(arr[index]).equals(c)){
return false;
}
}
if(map.containsKey(arr[i]) && !map.get(arr[i]).equals(c)){
return false;
}
map.put(arr[i], c);
count[c - 'a'] = i;
i++;
}
return true;
}
}
292. Nim 游戏
难度简单
列举了几个数字,从1 - 14.发现当n是4的倍数时一定返回false。所以大胆推测n = 4的倍数时一定会输。其余情况都会赢。
class Solution {
public boolean canWinNim(int n) {
if(n <= 3){
return true;
}
return n % 4 != 0;
}
}
299. 猜数字游戏
难度简单
比较简单的一题。利用两个count数组来确定公牛和奶牛的数量即可。
class Solution {
public String getHint(String secret, String guess) {
char[] arr1 = secret.toCharArray();
char[] arr2 = guess.toCharArray();
int[] count1 = new int[10];
int[] count2 = new int[10];
for(char c : arr1){
count1[c - '0']++;
}
for(char c : arr2){
count2[c - '0']++;
}
int A = 0;
int B = 0;
for(int i = 0;i < arr1.length;i++){
if(arr1[i] == arr2[i]){
count1[arr1[i] - '0']--;
count2[arr1[i] - '0']--;
A++;
}
}
for(int i = 0;i < 10;i++){
B += Math.min(count1[i], count2[i]);
}
return A + "A" + B + "B";
}
}
326. 3的幂
难度简单
普通的方法是这样做的。
class Solution {
public boolean isPowerOfThree(int n) {
if(n < 1 || n == 2){
return false;
}
while(n >= 3){
if(n % 3 != 0){
return false;
}
n /= 3;
}
return n == 1;
}
}
342. 4的幂
难度简单
和上一题一样
class Solution {
public boolean isPowerOfFour(int n) {
if(n < 4 && n != 1){
return false;
}
while(n >= 4){
if(n % 4 != 0){
return false;
}
n /= 4;
}
return n == 1;
}
}
345. 反转字符串中的元音字母
难度简单
最开始用了顺序遍历,发现超时了。
class Solution {
public String reverseVowels(String s) {
if(s == null){
return "";
}
// a e i o u
StringBuilder sb = new StringBuilder();
Set<Character> set = new HashSet<>();
set.add('a');
set.add('e');
set.add('i');
set.add('o');
set.add('u');
set.add('A');
set.add('E');
set.add('I');
set.add('O');
set.add('U');
List<Integer> list = new ArrayList<>();
char[] arr = s.toCharArray();
for(int i = 0;i < arr.length;i++){
if(set.contains(arr[i])){
list.add(i);
sb.append(String.valueOf(arr[i]));
}
}
String str = sb.reverse().toString();
int index = 0;
for(int i = 0;i < arr.length;i++){
if(list.contains(i)){
arr[i] = str.charAt(index++);
}
}
return String.valueOf(arr);
}
}
看了眼提示,发现可以用双指针来做。这题的双指针也比较简单。
class Solution {
public String reverseVowels(String s) {
if(s == null){
return "";
}
Set<Character> set = new HashSet<>();
set.add('a');
set.add('e');
set.add('i');
set.add('o');
set.add('u');
set.add('A');
set.add('E');
set.add('I');
set.add('O');
set.add('U');
char[] arr = s.toCharArray();
int begin = 0;
int end = arr.length - 1;
while(begin < end){
while(begin < end && !set.contains(arr[begin])){
begin++;
}
while(begin < end && !set.contains(arr[end])){
end--;
}
if(begin == end){
break;
}
char c = arr[begin];
arr[begin] = arr[end];
arr[end] = c;
begin++;
end--;
}
return String.valueOf(arr);
}
}
367. 有效的完全平方数
难度简单
双指针暴力超时
class Solution {
public boolean isPerfectSquare(int num) {
if(num == 1){
return true;
}
int begin = 1;
int end = num / 2;
int mid;
while(begin <= end){
mid = begin + (end - begin) / 2;
long temp = mid * (long)mid;
if(temp == num){
return true;
}else if(temp > num){
end--;
}else{
begin++;
}
}
return false;
}
}
不过如果用二分思想则可以通过。
class Solution {
public boolean isPerfectSquare(int num) {
if(num == 1){
return true;
}
int begin = 1;
int end = num / 2;
int mid;
while(begin <= end){
mid = begin + (end - begin) / 2;
long temp = mid * (long)mid;
if(temp == num){
return true;
}else if(temp > num){
end = mid - 1;
}else{
begin = begin + 1;
}
}
return false;
}
}
emmm,换了种思路,还是超时了。依次去算各个数字的平方,如果平方值与num相等的话,则说明是;如果平方值比num要大时,则结束循环,返回false。
class Solution {
public boolean isPerfectSquare(int num) {
int temp;
for(int i = 1;i <= num / 2;i++){
temp = i * i;
if(num == temp){
return true;
}
if(temp > num){
break;
}
}
return false;
}
}
383. 赎金信
难度简单
因为题目说了两字符串中只包含小写字母,所以用一个长度为26的数组就可以解决。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] count = new int[26];
for(char c : ransomNote.toCharArray()){
count[c - 'a']++;
}
for(char c : magazine.toCharArray()){
if(count[c - 'a'] > 0){
count[c - 'a']--;
}
}
for(int num : count){
if(num > 0){
return false;
}
}
return true;
}
}
387. 字符串中的第一个唯一字符
难度简单
比较简单的一题,借助一个set来判断前面有没有出现过字符,用indexOf来判断之后还有没有同一个字符。
class Solution {
public int firstUniqChar(String s) {
Set<Character> set = new HashSet<>();
for(int i = 0;i < s.length();i++){
char c = s.charAt(i);
int index = s.indexOf(c, i + 1);
if(!set.contains(c) && index == -1){
return i;
}
set.add(c);
}
return -1;
}
}
389. 找不同
难度简单
map是一种比较通用的解法。
class Solution {
public char findTheDifference(String s, String t) {
Map<Character,Integer> map1 = getCharMap(s);
Map<Character,Integer> map2 = getCharMap(t);
for(Map.Entry<Character, Integer> entry : map2.entrySet()){
if(!map1.containsKey(entry.getKey()) || map1.get(entry.getKey()) != entry.getValue()){
return entry.getKey();
}
}
return '0';
}
public Map<Character, Integer> getCharMap(String str){
Map<Character, Integer> map = new HashMap<>();
for(char c : str.toCharArray()){
if(map.containsKey(c)){
map.put(c, map.get(c) + 1);
}else{
map.put(c, 1);
}
}
return map;
}
}
其次还可以把字符串转变成char数组,对其进行排序,再进行逐位的判断。
看了题解发现有更简单的做法。因为t中只添加了一个字符,所以除了添加的字符,在s和t组成的字符串中剩余的字符出现的次数一定是偶数次。所以这个题目就变成了在字符串中只出现过奇数次数的字符。把所有的字符进行一个异或,最后得到的值再转变成char就是结果。
class Solution {
public char findTheDifference(String s, String t) {
char[] arr1 = s.toCharArray();
char[] arr2 = t.toCharArray();
if(arr1.length == 0){
return arr2[0];
}
int c = arr1[0] ^ arr2[0];
for(int i = 1;i < arr1.length;i++){
c ^= arr1[i] ^ arr2[i];
}
c ^= arr2[arr2.length - 1];
return (char)c;
}
}