import java.util.*;
class Solution {
public int romanToInt(String s) {
int sum=0;
int finalnum=0;
for(int i=0;i<s.length()-1;i++){
int prenum=getValue(s.charAt(i));
int num=getValue(s.charAt(i+1));
if(prenum<num){
sum=sum-prenum;
}else{
sum=sum+prenum;
}
finalnum=num;
}
sum=sum+finalnum;
return sum;
}
private int getValue(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;
default: return 0;
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rmsFqvjJ-1611496380890)(C:\Users\HASEE\AppData\Roaming\Typora\typora-user-images\1611461674333.png)]
错误例子如上图。
原因在于我的循环用的怪怪的。等于是假设了字符串至少有两位,遇到只有一位的情况出错了。
正确解法如下:
import java.util.*;
class Solution {
public int romanToInt(String s) {
int sum=0;
int prenum=getValue(s.charAt(0));
for(int i=1;i<s.length();i++){
int num=getValue(s.charAt(i));
if(prenum<num){
sum=sum-prenum;
}else{
sum=sum+prenum;
}
prenum=num;
}
sum=sum+prenum;
return sum;
}
private int getValue(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;
default: return 0;
}
}
}
import java.util.*;
class Solution {
public String longestCommonPrefix(String[] strs){
if(strs == null||strs.length==0){
return "";
}
int count=strs.length;
int length=strs[0].length();
for(int i=0;i<length;i++){
char c=strs[0].charAt(i);
for(int j=1;j<count;j++){
if(i==strs[j].length()||strs[j].charAt(i) != c){
//重点复习
return strs[0].substring(0,i);
}
}
}
return strs[0];
}
}
错误:
import java.util.*;
class Solution {
public String longestCommonPrefix(String[] strs){
if(strs == null||strs.length==0){
return "";
}
int count=strs.length;
int length=strs[0].length();
for(int i=0;i<length;i++){
char c=strs[0].charAt(i);
for(int j=1;j<count;j++){
if(strs[j].charAt(i) != c||i==strs[j].length()){
//重点复习
return strs[0].substring(0,i);
}
}
}
return strs[0];
}
}
import java.util.HashMap;
class Solution {
public boolean isValid(String s) {
Map<Character,Character> pair=new HashMap<Character,Character>(){
{
put(')','(');
put(']','[');
put('}','{');
}};
Deque<Character> stack=new LinkedList<Character>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(pair.containsKey(ch)){
if(stack.isEmpty()||stack.peek()!=pair.get(ch)){
return false;
}
stack.pop();
}else{
stack.push(ch);
}
}
return stack.isEmpty();
}
}
HashMap的初始化值得注意。声明时初始化速度较快。
栈也是一种表。pop()弹出栈顶值,peek()访问栈顶值。
解法很妙。
import java.util.HashMap;
class Solution {
public boolean isValid(String s) {
Map<Character,Character> pair=new HashMap<Character,Character>();
pair.put(')','(');
pair.put(']','[');
pair.put('}','{');
//这种初始化方法较上面声明时初始化速度慢。
Deque<Character> stack=new LinkedList<Character>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(pair.containsKey(ch)){
if(stack.isEmpty()||stack.peek()!=pair.get(ch)){
return false;
}
stack.pop();
}else{
stack.push(ch);
}
}
return stack.isEmpty();
}
}
当一个函数用它自己来定义时就称为是递归。
不断剔除两个链表中的最小值
解法一:递归
/**
* 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 {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 ==null){
return l2;
}
if(l2 ==null){
return l1;
}
if(l1.val<l2.val){
l1.next=mergeTwoLists(l1.next,l2);
return l1;
}else{
l2.next=mergeTwoLists(l1,l2.next);
return l2;
}
}
}
方法巧妙,但也难想。
思路就是函数功能是返回两个链表的最小值。递归一次返回一个最小值然后将剩下的节点再输入函数作递归,一步步直到出现空链表,递归结束。
解法二:迭代
/**
* 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 {
ListNode prehead=new ListNode(-1);//prehead是头节点
ListNode prev=prehead;//prev是移动节点
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
/*if(l1 ==null){
return l2;
}
if(l2 ==null){
return l1;
}
if(l1.val
while(l1!= null&&l2!=null){
if(l1.val<l2.val){
prev.next=l1;
l1=l1.next;
}else{
prev.next=l2;
l2=l2.next;
}
prev=prev.next;
}
prev.next=l1==null?l2:l1;
return prehead.next;//从第二个节点开始返回
}
}
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length==0) return 0;
int i=0;
for(int j=1;j<nums.length;j++){
if(nums[j]!=nums[i]){
i++;
nums[i]=nums[j];
}
}
return i+1;
}
}
这个解法双指针用的巧妙,自愧不如。人这双指针真是优雅。
i是慢指针,j是快指针,只有找到不同值时i+1,把nums[j]的值赋给nums[i+1],nums[j]=nums[i]时就让快指针加。
package com.leetcode;
import com.BeforeShiErZhang.QuadrangleUseInterface;
public class question {
public int removeDuplicates(int[] nums) {
int length = 0;
for (int i = 0; i < nums.length; i++) {
int j=i;
while(j<nums.length&&nums[j]==nums[i]){
j++;
}
length = i ;
}
return length;
}
public static void main(String[] args) {
question q1=new question();
System.out.println(q1.removeDuplicates(new int[]{
0, 0, 1, 1, 1, 2, 2, 3, 3, 4}));
}
}
这是我的解法,在内层循环中找到不一样的值之后不知道怎么停下来,只能一直找到最大的。
class Solution {
public int removeElement(int[] nums, int val) {
int i=0;
for(int j=0;j<nums.length;j++){
if(nums[j]!=val){
nums[i]=nums[j];
i++;
}
}
return i;
}
}
class Solution {
public int strStr(String haystack, String needle) {
//解法一:滑动窗口
/* int n=haystack.length();
int L=needle.length();
for(int start=0;start
//解法二:双指针
int n=haystack.length();
int L=needle.length();
if(L==0) return 0;
int pn=0;
while(pn<n-L+1){
while(pn<n-L+1&&haystack.charAt(pn)!=needle.charAt(0)) ++pn;
int pl=0;
int err=0;
while(pl<L&&pn<n&&haystack.charAt(pn)==needle.charAt(pl)){
++pn;
++pl;
++err;
}
if(err==L) return pn-L;
pn=pn-err+1;//当字符串并不完全匹配时,返回到起始位置加1的位置重新匹配。
}
return -1;
}
}
class Solution {
public String countAndSay(int n) {
if(n==1) return "1";//递归的第一件事就是要确定递归结束条件。
String str=countAndSay(n-1);//上一轮的输出是这一轮的输入,这就是递归。
StringBuffer ans=new StringBuffer();
int start=0;
//提供此解法的大神说“递归代码最神的地方就是一个循环可以展现出n个嵌套for()循环。
//这里的算法在初级算法Lc中经常用到,当与前一个元素不一样时出发函数
//从1开始是为了方便对比,长度也+1方便对比”
for(int i=1;i<str.length()+1;i++){
//必须得是str.length()+1,因为遍历到最后一位时,不管最后两位相等与否,都需要i+1,来描述最后一位或最后两位数字的个数。
if(i==str.length()){
ans.append(i-start).append(str.charAt(start));
}else if(str.charAt(i)!=str.charAt(start)){
ans.append(i-start).append(str.charAt(start));//StringBuffer类可以直接对StringBuffer对象本身操作,而不是生成新的对象。 像本例的append()方法,直接添加字符进入字符串,最后直接toString()转换为字符串,功能强大。
start=i;//双指针遍历
}
}
return ans.toString();
}
}
目前的水平仅仅是能够看着解答做出简单题,解答里的一些细节还值得仔细琢磨。不能直接看解答,自己硬想却又耽误时间,所以在保证效率的基础上,看题目自己思考,有个大致思路后再看解答的方法。