第一天刷到的就是贪心算法,还是比较经典的。
用变量维护两个变量的数量差,当变量等于0就说明这两个是平衡字符串。
class Solution {
public int balancedStringSplit(String s) {
int ans = 0, d = 0;
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (ch == 'L') {
++d;
} else {
--d;
}
if (d == 0) {
++ans;
}
}
return ans;
}
}
后边也有用到类似的方法的。
第二天是个两数之和:
其中一个是暴力列举,然后另一个就是利用哈希表,此处就贴出来哈希表的。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
hashtable.put(nums[i], i);
}
return new int[0];
}
}
这里边主要是运用了哈希表的特性,因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N)O(N) 降低到 O(1)O(1)。这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
第三天是个整数反转的,比较简单,直接贴代码
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {
return 0;
}
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
}
第四天是个回文数,就直接用的上边整数反转的代码。这就不贴代码了。
第五天是罗马数转整数:
主要是逻辑,没啥算法,也是本人第一次没看题解做出来。
class Solution {
public int romanToInt(String s) {
int ans=0;
int lm[]=new int[s.length()];
for(int i =0; i<s.length();++i){
char ch=s.charAt(i);
lm[i]=swtichx(ch);
}
for (int i = 0; i <lm.length ; i++) {
if (i + 1 < lm.length) {
if (lm[i] >= lm[i + 1]) {
ans += lm[i];
} else {
ans += lm[i + 1] - lm[i];
i++;
}
}else{
ans+=lm[i];
}
}
return ans;
}
public static int swtichx(char ch) {
switch (ch) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
}
return 0;
}
}
第六天是一个最长公共前缀的题目,也是自己慢慢用比较笨的方法磨出来的
class Solution {
public String longestCommonPrefix(String[] strs) {
String ans="";
if(strs.length>=2){
String x = strs[0];
String z = strs[1];
for (int j = 0; j < strs[0].length(); j++) {
if(j<z.length()&&j<x.length()) {
if (x.charAt(j) == z.charAt(j)) {
ans += x.charAt(j);
}else{
break;
}
}
}
for (int i = 2; i < strs.length; i++) {
for (int j = 0; j <ans.length() ; j++) {
if(j<strs[i].length()) {
if (ans.charAt(j) != strs[i].charAt(j)) {
ans = ans.substring(0, j);
}
}else {
ans=ans.substring(0,j);
}
}
}
return ans;}
else{
return strs[0];
}
}
}
第7天就是比较经典的括号匹配了,也是看完题解明白的。
class Solution {
public boolean isValid(String s) {
int n = s.length();
if (n % 2 == 1) {
return false;
}
Map<Character, Character> pairs = new HashMap<Character, Character>() {{
put(')', '(');
put(']', '[');
put('}', '{');
}};
Deque<Character> stack = new LinkedList<Character>();
for (int i = 0; i < n; i++) {
char ch = s.charAt(i);
if (pairs.containsKey(ch)) {
if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
return false;
}
stack.pop();
} else {
stack.push(ch);
}
}
return stack.isEmpty();
}
}
还是自己理解挺久的。。。。
第8天是个合并两个有序链表的,这个比较简单,主要是运用了一个递归的思想。
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
第9天是个删除有序数组中的重复项,运用了经典的双指针。
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
int fast = 1, slow = 1;
while (fast < n) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
}
第10天是个实现strStr(),也是用的暴力匹配,第二种算法太恐怖了看起来,看不心里去,
class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length(), m = needle.length();
for (int i = 0; i + m <= n; i++) {
boolean flag = true;
for (int j = 0; j < m; j++) {
if (haystack.charAt(i + j) != needle.charAt(j)) {
flag = false;
break;
}
}
if (flag) {
return i;
}
}
return -1;
}
}
这几天的刷题,主要是双指针和暴力匹配的思想给我留下比较深的印象。以及在设置一个变量记录变化的这个思路也是很好的!!!
就继续坚持吧,放假了就没继续,开学了还是会继续的!!!gogogo