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***
}
}
/**
* 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;
}
}
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;
}
}
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;
}
}
}
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;
}
}
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;
}
}
/**
* 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;
}
}
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;
}
}
class Solution {
public int strStr(String haystack, String needle) {
int index = haystack.indexOf(needle);
return index;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
/**
* 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;
}
}
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;
}
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;
}
}