- Eg1.
//①只有數組纔可以有length方法,鏈表不可
// ②即使在內循環for有了return,主函數也要有return
class Solution {
public int[] twoSum(int[] nums, int target) {
int ans;
for(int i = 0; i < nums.length; i ++){
ans = target - nums[i];
***//①只有數組纔可以有length方法,鏈表不可***
for(int j = i + 1; j < nums.length; j++){
if(nums[j] == ans)
**return new int[] {i,j};**
}
}
**return null;** // ***②即使在內循環for有了return,主函數也要有return***
}
}
- Eg2.
//②一個循環解決一個循環的問題,不要將上一個循環的值留到下一個循環來填寫
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//以l1鏈爲默認鏈
ListNode p, q;
int temp, carry = 0;
//此處for的判斷條件沒用
for(p = l1, q = l2; p != null && q != null; p = p.next, q = q.next){
//計算包括三部分:a、b、進位
temp = p.val + q.val + carry ;
//進位置0
carry = 0;
//如果有進位
if(temp > 9){
carry = 1;
temp = temp % 10;
}
//判斷某個鏈表是不是到頭了,***①有三種情況***
//如果兩個都到頭
if(p.next == null && q.next == null){
p.val = temp;
if(carry == 1)
p.next = new ListNode(1);
return l1;
}
if(p.next == null){
p.val = temp;
p.next = q.next;
p = p.next;
break;
}
if (q.next == null) {
p.val = temp;
p = p.next;
break;
}
//填數
p.val = temp;
}
***//②一個循環解決一個循環的問題,不要將上一個循環的值留到下一個循環來填寫***
while(p.next != null){
temp = p.val + carry;
carry = 0;
if(temp > 9){
carry = 1;
temp = temp % 10;
}
//填數
p.val = temp;
p = p.next;
}
//判斷最高位是否需要擴展
temp = p.val + carry;
if (temp > 9) {
temp = temp % 10;
p.next = new ListNode(1);
}
p.val = temp;
return l1;
}
}
- Eg9.
- 1.Line 10: error: cannot find symbol [in Driver.java]
boolean ret = new Solution().isPalindrome(param_1);
^
symbol: method isPalindrome(int)
location: class Solution
由於這道題是判斷迴文題,這個錯誤是說,你的函數名稱要用isPalindrome
//①求整數的位數:循環,將除數不斷乘10,直至商爲個位數
//②將number截取首位與尾位:求餘,再對餘數除以10
- 1.Line 10: error: cannot find symbol [in Driver.java]
import java.lang.String;
class Solution{
public boolean isPalindrome(int number){
//負數統統不是迴文數
if (number < 0)
return false;
// 位數多於1的判斷
//判斷數字的迴文性,循環取最高位與最低位
//1.先求number的位數,temp1存的是number的數量級10 100 1000
int temp1 = 1;
int temp2 = number/temp1;
int topNum = 0 , bottomNum = 0;
//①求整數的位數:循環,將除數不斷乘10,直至商爲個位數
while (temp2 >= 10){
temp1 *= 10;
temp2 = number / temp1;
}
//循環取最高位與最低位
//如果condition爲 number>=10,那麼就會分不清10011跟111這種情況,
//上述這兩種情況區別在於他們的temp1存儲的數量級不同
while (number > 0){
//取首位跟尾位
topNum = number / temp1;
bottomNum = number % 10 ;
if (topNum != bottomNum)
return false;
//②將number截取首位與尾位:求餘,再對餘數除以10
number = number%temp1/10;
// number = number / 10;
temp1 /= 100;
}
return true;
}
}
- Eg 13. 羅馬數字
//①靜態函數只能調用靜態函數,故該子函數需要用static修飾
//②由於switch內部語句是return,所以無需break
//③遍歷String字符串,使用string.charAt(index),返回char
class Solution {
public int romanToInt(String s) {
int length = s.length();
int pre = 65535, cur = 0;
int sum = 0;
char temp;
//掃描
for(int i = 0; i < length; i++){
***//③遍歷String字符串,使用string.charAt(index),返回char***
temp = s.charAt(i);
cur = invertInt(temp);
if(pre >= cur)
sum += cur;
else
sum = sum - 2*pre + cur;
pre = cur;
}
return sum;
}
public int invertInt(char str){
***//②由於switch內部語句是return,所以無需break***
switch (str){
case 'I':
return 1;
//break;
case 'V':
return 5;
// break;
case 'X':
return 10;
//break;
case 'L':
return 50;
// break;
case 'C':
return 100;
//break;
case 'D':
return 500;
// break;
case 'M':
return 1000;
// break;
default:
return -1;
}
}
}
- Eg14. 最長公共子串
Line 9: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length
//①當初出現的錯誤是minlen = strs[0].length()這個語句Index 0 out of bounds for length 0。所以問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length
//②Java求字符串長度:String.length()
//③Java求數組元素個數:String[].length;
import java.util.Arrays;
class Solution {
public String longestCommonPrefix(String[] strs) {
String comStr = "";
if(strs.length == 0) return comStr;
***//①當初出現的錯誤是minlen = strs[0].length()這個語句Index 0 out of bounds for length 0
//所以問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length***
// if (Arrays.asList(strs).contains("")){
// return comStr;
//}
***//②Java求字符串長度:String.length()
//③Java求數組元素個數:String[].length;***
int minlen = strs[0].length(), curlen;
char curchar;
//對數組進行遍歷,求數組最短元素的長度
for (int i = 0 ; i < strs.length; i++) {
curlen = strs[i].length();
if (curlen < minlen)
minlen = curlen;
}
//外層對首元素進行遍歷,遍歷次數爲最短元素的長度minlen
for (int i = 0; i < minlen; i++) {
curchar = strs[0].charAt(i);
//內層對所有元素遍歷
for (int j = 1; j < strs.length; j++) {
if (curchar != strs[j].charAt(i))
return comStr;
}
comStr += curchar;
}
return comStr;
}
}
- Eg20.有效的括號
//①注意此處s是字符串String型,故不能用數組取元素s[i]的方式
class Solution {
public boolean isValid(String s) {
if (s == "") return true;
int length = s.length(), rear = -1;
char[] stack = new char[length];
char temp;
***//①注意此處s是字符串String型,故不能用數組取元素s[i]的方式***
for(int i = 0; i < length; i++) {
if (s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{')
stack[++rear] = s.charAt(i);
if (s.charAt(i) == ')' || s.charAt(i) == ']' || s.charAt(i) == '}'){
if (rear == -1) return false;
temp = stack[rear];
if ((temp == '(' && s.charAt(i) == ')') || (temp == '[' && s.charAt(i) == ']') || (temp == '{' && s.charAt(i) == '}'))
rear--;
else
return false;
}
}
if (rear >= 0) return false;
return true;
}
}
- Eg21.合併兩個鏈表
//①Java中,p是class,condition不能直接是while(p&&q)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
//思路:1.確定是要轉移結點還是複製結點,由於Java指針不方便使用,我選擇複製結點
//2.確定有多少個指針:新鏈表頭指針、尾指針,l1、l2的運動指針,新節點的指針
//3.新鏈表有結點時,與無結點時分別又是如何:有結點時要連接結點,更換尾指針;
//無結點時頭指針跟尾指針都要指向新節點
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
//由於下述需要用到list,r,n的判斷,所以要初始化
ListNode list = null ;
ListNode p = l1, q = l2, r = null, n = null; //r指向新鏈表尾,n指向新的結點
***//①Java中,p是class,condition不能直接是while(p&&q)***
while (p != null && q != null) {
if (p.val <= q.val) {
n = new ListNode(p.val, null);
if (list == null)
list = n;
else
r.next = n;
r = n;
p = p.next;
}
else {
n = new ListNode(q.val, null);
if (list == null)
list = n;
else
r.next = n;
r = n;
q = q.next;
}
}
if (p != null)
r.next = p;
if (q != null)
r.next = q;
return list;
}
}
- Eg26.刪除排序數組中的重複項
class Solution {
public int removeDuplicates(int[] nums) {
//符合條件,新鏈表更改再移動j,否則僅僅移動j
int i = 0, j = 1;
while (j < nums.length) {
if (nums[j] != nums[i]) {
nums[i+1] = nums[j];
i++;
}
j++;
}
return i+1;
}
}
- Eg28. 查詢子字符串的位置
調用String.indexOf()方法,若不存在,自動返回-1
class Solution {
public int strStr(String haystack, String needle) {
int index = haystack.indexOf(needle);
return index;
}
}
- Eg38.外觀數列
//①Java將char型轉換爲int型最簡單的方法是 int b = char - ‘0’ ;
//即char隱式轉換成int型時,轉爲對應的ASCII值
//②Java當int與char/String共同運算時,會自動轉換爲char/String
class Solution {
public String countAndSay(int n) {
if (n == 0) return "";
int i = 1;
String res = "1";
while (i < n) {
res = getSay(res);
i++;
}
return res;
}
public String getSay(String lastNum) {
String res = "";
int flag = 1, k = 0; //flag標記當前字符是否與上一個字符相同;k計數連續的字符數;當flag=0時,k=0
char curchar;
int curnum;
for (int i = 0; i < lastNum.length(); i++) {
curchar = lastNum.charAt(i); //當前數字字符
curnum = curchar - '0'; //當前數字
***//①Java將char型轉換爲int型最簡單的方法是 int b = char - '0' ;
//即char隱式轉換成int型時,轉爲對應的ASCII值***
if (i == 0)
k++;
else {
if (curchar == lastNum.charAt(i-1) ) //如果字符連續相等
k ++ ;
else{
***//②Java當int與char/String共同運算時,會自動轉換爲char/String***
res = res + k + lastNum.charAt(i-1);
k = 1;
}
}
}
res = res + k + lastNum.charAt(lastNum.length()-1);
return res;
}
}
- Eg53.最大子序和 (重做!!!)
//找具有最大和的連續數組,即動態規劃問題(對應做兼職賺錢賺取最多的錢)。思路:求每一步的最優解,再求全局的最優解
//每一步求當前的最大和:取(與上一步的最大和相加):sum=sum+nums[i]
//不取(自身等於最大和):sum = nums[i]
//①Java求最大值的函數:Math.max()
import java.util.*;
class Solution {
public int maxSubArray(int[] nums) {
//找具有最大和的連續數組,即動態規劃問題(對應做兼職賺錢賺取最多的錢)。思路:求每一步的最優解,再求全局的最優解
//每一步求當前的最大和:取(與上一步的最大和相加):sum=sum+nums[i]
//不取(自身等於最大和):sum = nums[i]
if (nums.length == 0) return 0;
//數組dp存取每一步的最優解
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
max = Math.max(dp[i], max);
}
return max;
}
}
-Eg58.最後一個單詞的長度
//①Java也有跟Python一樣的String.split()分割字符串的方法,但是要用字符號串數組存儲
class Solution {
public int lengthOfLastWord(String s) {
String[] strlist = s.split(" ");
int listlen = strlist.length;
if (listlen == 0) return 0;
int length = strlist[listlen-1].length();
return length;
}
}
- Eg67.二進制求和
//①Java char轉int型: char - ‘0’;
//②Java int轉String型: Integer.String();
class Solution {
public String addBinary(String a, String b) {
int blen = b.length(), alen = a.length(), maxlen = Math.max(alen, blen);
int t1, t2, carry=0,temp;
int deltalen = Math.abs(blen-alen);
String s = "";
if (blen > alen)
while ((deltalen--) > 0)
a = "0" + a;
else
while ((deltalen--) > 0)
b = "0" + b;
for (int i = maxlen-1; i >= 0; i--) {
t1 = b.charAt(i) - '0';
t2 = a.charAt(i) - '0';
temp = (t1 + t2 + carry) % 2;
carry = (t1 + t2 + carry) / 2;
s = Integer.toString(temp) + s;
}
if (carry == 1)
s = "1" + s ;
return s;
}
}
- Eg70. 爬樓梯
//爬樓梯問題:斐波拉契數列問題
//特徵:每一步都可以化爲解決一步,剩下的小問題交給下一個人解決(移動磚頭問題)
//此處:若要走n階臺階,需要兩步。第一步:走1個臺階,剩下的n-1步由n-1步走法決定(設爲afa步);
//或者,第一步:走2個臺階,剩下的n-2步由n-2步走法決定(設爲beta步)。
//所以走n步臺階,有總共afa+beta步
class Solution {
public int climbStairs(int n) {
int start1 = 1, start2 = 2;
int temp = 0;
if (n == 1) return start1;
if (n == 2) return start2;
for (int i = 3; i <= n; i++) {
temp = start1 + start2;
start1 = start2;
start2 = temp;
}
return temp;
}
}
- Eg100 相同的樹.【重做】
重點:結點爲空時,讓其值爲-65535,不爲空時,讓其值爲真實val。這樣會讓隊列遍歷方便很多
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
//根節點相同的情況下
TreeNode ptr = p, qtr = q;
TreeNode[] l1 = new TreeNode[1000], l2 = new TreeNode[1000];
int temp1, temp2, front1, front2, rear1, rear2;
front1 = front2 = rear1 = rear2 = -1;
l1[++rear1] = ptr;
l2[++rear2] = qtr;
int val1, val2;
//用隊列層次遍歷樹,當隊列不空時,樹未遍歷結束
while (front1!=rear1 && front2!=rear2) {
//出隊列
ptr = l1[++front1];
qtr = l2[++front2];
//彈出隊首結點。如果該節點不爲空,將其左右結點壓入隊列;如果爲空,僅僅彈出
if (ptr == null)
val1 = -65535;
else {
val1 = ptr.val;
l1[++rear1] = ptr.left;
l1[++rear1] = ptr.right;
}
if (qtr == null)
val2 = -65535;
else {
val2 = qtr.val;
l2[++rear2] = qtr.left;
l2[++rear2] = qtr.right;
}
//如果結點不同,結束循環
if (val1 != val2)
return false;
}
return true;
}
}
- Eg 101對稱二叉樹(重做)
//該層所有元素出列後,判斷該層元素是否鏡像對稱,此時下一層元素也全部進隊列
//當時出現的錯誤:對於用例[1,2,2,null,3,3,null]時,在遍歷第3層時,flag爲第2個null
//當指針指向第一個null時,condition爲ptr(=null) == flag,誤以爲到了該層次結尾
//edition2:由於我把null的情況用-65535來代替,所以我只需要計算出隊的結點數,判斷其是否等於層數
//condition 爲(count+1) == (int)Math.pow(2,level-1)) 這個想法又錯了,問題出在空節點無法掛左右空節點
//所以某層的總數不爲Math.pow(2,level-1)
//所以要用incnt跟outcnt來對進出隊列計數
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
TreeNode ptr = root;
TreeNode[] list = new TreeNode[1000];
//outcnt計算該層出隊列的數,incnt計算該層進隊列的數,注意數字下標(outcnt)從1開始
int front = -1, rear = -1, val, outcnt = 0, incnt = 1;
int[] numarr = new int[1000];
list[++rear] = ptr;
while (front != rear) {
ptr = list[++front];
if (ptr == null) val = -65535;
else {
val = ptr.val;
list[++rear] = ptr.left;
list[++rear] = ptr.right;
}
numarr[++outcnt] = val;
//該層所有元素出列後,判斷該層元素是否鏡像對稱,此時下一層元素也全部進隊列
//當時出現的錯誤:對於用例[1,2,2,null,3,3,null]時,在遍歷第3層時,flag爲第2個null
//當指針指向第一個null時,condition爲ptr(=null) == flag,誤以爲到了該層次結尾
//edition2:由於我把null的情況用-65535來代替,所以我只需要計算出隊的結點數,判斷其是否等於層數
//condition 爲(count+1) == (int)Math.pow(2,level-1)) 這個想法又錯了,問題出在空節點無法掛左右空節點
//所以某層的總數不爲Math.pow(2,level-1)
//所以要用incnt跟outcnt來對進出隊列計數
if (outcnt == incnt){
//注意數字下標(outcnt)從0開始
for (int i = 1, j = outcnt; i < j; i++, j--) {
if (numarr[i] != numarr[j])
return false;
}
//如果該層鏡像對稱,重新set
incnt = rear - front;
outcnt = 0;
}
}
return true;
}
}
===========================
遞歸算法:
compare (leftNode, rightNode) {
if (leftNode != null && rightNode != null)
return leftNode.val == rightNode.val ? compare(leftNode.left, rightNode.right) && compare(leftNode.right, rightNode.left) : false;
return leftNode == null && rightNode == null;
}
- Eg125(驗證迴文串)
//①Java字符串用正則表達式時採用String.replaceAll();
//②a比A多32
//核心:將大寫字符全部轉爲小寫字符
class Solution {
public boolean isPalindrome(String s) {
//①Java字符串用正則表達式時採用String.replaceAll();
//②a比A多32
String str = s.replaceAll("[^a-zA-Z0-9]","");
char left, right;
for (int i=0, j=str.length()-1; i < j ;i++, j-- ) {
left = str.charAt(i);
right = str.charAt(j);
if(left >= 'A' && left <= 'Z')
left = (char)(left+32);
if(right >= 'A' && right <= 'Z')
right = (char)(right+32);
if(left != right)
return false;
}
return true;
}
}