力扣笔记之字符串常见题型

记录刷力扣时的一些技巧(字符串)

判断str前缀是否为a

str.startsWith(a) ;

切片字符串

str.substring(left,right) ;

分隔

String []arr = str.split(" ") ;

可以替换String.split()的方法

int i = 0 ,j = 0;
int a=0;
while(i < version1.length())
{
    a=0;
    while(i < version1.length() && version1.charAt(i) != '.')
            a = a * 10 + version1.charAt(i++) - '0';
    i++;
}

合并

String.jion(" ",strs) ;

哈希表

Map<Character, Integer> map = new HashMap<>();
for (char ch : s.toCharArray()) {
   map.put(ch, map.getOrDefault(ch, 0) + 1);
}

排序
箭头前是参数,箭头后是要干什么

ArrayList<Character> list = new ArrayList<>(map.keySet());
list.sort((a,b)->{
            //从大到小
                return map.get(b)-map.get(a);
            }
        );

整数转罗马数字

int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};    
String reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 
StringBuilder res = new StringBuilder();
for(int i=0; i<13; i++){
    while(num>=values[i]){
        num -= values[i];
        res.append(reps[i]);
    }
}
return res.toString();

字符串数字相加(各进制通用)

StringBuilder sb = new StringBuilder();
int carry = 0, i = num1.length()-1, j = num2.length()-1;
while(i >= 0 || j >= 0 || carry != 0){
    if(i>=0) carry += num1.charAt(i--)-'0';
    if(j>=0) carry += num2.charAt(j--)-'0';
    sb.append(carry%10);
    carry /= 10;
}
return sb.reverse().toString();

如果为链表相加呢?
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
思路:先用栈取值,然后头插法

public ListNode addInList (ListNode head1, ListNode head2) {
        // write code here
        Stack<Integer> stack1 = new Stack() ;
        Stack<Integer> stack2 = new Stack() ;
        while(head1 != null){
            stack1.push(head1.val) ;
            head1 = head1.next ;
        }
        while(head2 != null){
            stack2.push(head2.val) ;
            head2 = head2.next ;
        }
        int carry = 0 ;
        ListNode dummy = new ListNode(0) ;
        while(!stack1.isEmpty() || !stack2.isEmpty() || carry != 0){
            ListNode node = new ListNode(0) ;
            if(!stack1.isEmpty()) carry += stack1.pop() ;
            if(!stack2.isEmpty()) carry += stack2.pop() ;
            node.val = carry%10 ;
            carry /= 10 ;
            node.next = dummy.next ;
            dummy.next = node ;
        }
        return dummy.next ;
    }

kmp算法

def get_next(s):
    '''
    获取字符串最大的前后缀交集长度列表next
    e.g.: s = 'abcabe' -> next = [-1, 0, 0, 0, 1, 2]
    *******前后缀名词解释*******
    s的前缀为: 'a', 'ab', 'abc', 'abca', 'abcab'
    s的后缀为:'bcabe', 'cabe', 'abe', 'be', 'e'

    *******生成next列表的规则*******
    对s进行遍历的时候,next列表按照如下生成(计算next的值时不看最后一位):
    a - next[0] = -1
    ab - 无交集 0
    abc - 无交集 0
    abca - 无交集 0
    abcab - 交集 a 1
    abcabe - 交集ab 2
    '''
    # 初始化next列表
    l_next = [-1] * len(s)
    # 初始化循环指针,j为字符串遍历指针,k为生成next列表的循环指针
    j, k = 0, -1
    # 遍历字符串s
    while j < len(s) - 1:
        # 当k未指向字符串时,或者s[j]和s[k]相等时,j和k均往后移动一位
        # 然后,next列表next[j]保存k指针指向的位置
        if k == -1 or s[j] == s[k]:
            j += 1
            k += 1
            l_next[j] = k  # next列表next[j]保存k指针指向的位置
        else:
            # 这一句是非常关键的,也是最难理解的
            # 我也只是大概理解了,还未深入理解
            # 如果k已经指向字符串列表,并且s[j]不等于s[k]时
            # k指针回溯,意思是将k指向next列表next[k]的位置
            # 相当于是指向之前的一次s[j]==s[k]的位置
            k = l_next[k]
    return l_next
def KMP(s: str, p: str) -> int:
    '''
    s - 目标字符串;p - 待匹配子串
    返回子串在目标字符串中的索引位置
    '''
    i = j = 0
    l_next = get_next(p)
    print('next:', l_next)
    # 遍历两个字符串
    while i < len(s) and j < len(p):
        print('*' * 20)
        print(' '*i + 'v')
        print(s)
        print(' '*(i-j) + p)
        print(' '*i + '^')
        if j == -1 or s[i] == p[j]:
            i += 1
            j += 1
        else:
            j = l_next[j]

        # 字符串越界保护
        if i >= len(s) or j >= len(p): break
        # 如果子串p尾部超过了目标字符串,则不用再往后移动比较了
        if i-j + len(p) > len(s): return -1
    if j == len(p):
        return i - j
    return -1

if __name__ == '__main__':
    s, p = 'abcabcb', 'abcb'
    print('=' * 30)
    print('return:', KMP(s, p))

判断是不是回文串

public boolean ishuiwen(String s){
        int start=0,end=s.length();
        while(start<end){
            if(s.charAt(start)==s.charAt(end)){start++;end--;}
            else return false;
        }
        return true;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值