java算法入门之有效的括号删除有序数组中的重复项实现strStr

下面我将详细讲解“java算法入门之有效的括号删除有序数组中的重复项实现strStr”的完整攻略。

1. 题目描述

这个问题由两部分组成。

1.1 删除有效的括号

给定一个括号字符串 s,删除尽可能多的括号,使得 s 合法,并返回删除后的字符串。

输入:s = "lee(t((c)o)de)"
输出:"lee(t(c)o)de"
解释:"lee(t(co)de)"、"lee(t(c)ode)" 也是一个可行的答案。

输入:s = "a)b(c)d"
输出:"ab(c)d"

1.2 删除有序数组中的重复项实现 strStr

给定一个排序数组 nums,删除重复出现的元素,使每个元素只出现一次,返回新数组的长度。你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

题目同时要求实现 strStr 函数,输入一个字符串 haystack 和一个子串 needle,在 haystack 字符串中找出 needle 子串出现的第一个位置(从 0 开始)。如果不存在,则返回 -1。

2. 解题思路

2.1 删除有效括号的算法步骤

  1. 维护一个栈,用于存储合法字符串的左括号下标;
  2. 遍历字符串 s,如果当前字符为左括号,则将其下标入栈;
  3. 如果当前字符为右括号,分两种情况:
  4. 栈顶为左括号,则直接将栈顶元素出栈;
  5. 栈顶不为左括号,则将当前字符下标入栈。
  6. 遍历结束后,再次遍历栈中存储的下标,将对应的字符替换为空串。

2.2 删除有序数组中的重复项实现 strStr 的算法步骤

  1. 当 nums 数组为空或只有一个元素时,直接返回长度即可;
  2. 定义两个指针 i 和 j,分别指向第一个元素和第二个元素;
  3. 遍历数组,当 nums[i] 等于 nums[j] 时,j 向右移动一位;
  4. 当 nums[i] 不等于 nums[j] 时,将 nums[j] 赋值给 nums[i+1],然后 i 和 j 都向右移动一位;
  5. 遍历结束后,新数组的长度即为 i + 1;
  6. 接着实现 strStr 函数:比较 haystack 中的每个子串是否与 needle 相等,如果相等,则返回相应的下标;如果遍历结束后仍没有找到匹配的字符串,则返回 -1。

3. 代码实现

3.1 删除有效括号的代码实现

public String removeInvalidParentheses(String s) {
    Stack<Integer> stack = new Stack<>();
    char[] ch = s.toCharArray();
    for (int i = 0; i < ch.length; i++) {
        if (ch[i] == '(') {
            stack.push(i);
        } else if (ch[i] == ')') {
            if (!stack.isEmpty() && ch[stack.peek()] == '(') {
                stack.pop();
            } else {
                stack.push(i);
            }
        }
    }
    StringBuilder sb = new StringBuilder(s);
    while (!stack.empty()) {
        sb.deleteCharAt(stack.pop());
    }
    return sb.toString();
}

3.2 删除有序数组中的重复项并实现 strStr 的代码实现

public int removeDuplicates(int[] nums, String haystack, String needle) {
    int len = nums.length;
    if (len <= 1) {
        return len;
    }
    int i = 0, j = 1;
    while (j < len) {
        if (nums[i] == nums[j]) {
            j++;
        } else {
            nums[i + 1] = nums[j];
            i++;
            j++;
        }
    }
    // 实现 strStr 函数
    int n = haystack.length();
    int m = needle.length();
    if (m == 0) {
        return 0;
    }
    for (int k = 0; k <= n - m; k++) {
        if (haystack.substring(k, k + m).equals(needle)) {
            return k;
        }
    }
    return -1;
}

4. 示例说明

4.1 示例一:删除有效的括号

输入:s = "lee(t((c)o)de)"
输出:"lee(t(c)o)de"

利用上述第 3.1 小节的代码实现可得:

String s = "lee(t((c)o)de)";
String res = removeInvalidParentheses(s);
System.out.println(res); // lee(t(c)o)de

4.2 示例二:删除有序数组中的重复项实现 strStr

输入:nums = [1, 2, 2, 3, 4, 4, 5], haystack = "hello,world", needle = "world"
输出:6

利用上述第 3.2 小节的代码实现可得:

int[] nums = {1, 2, 2, 3, 4, 4, 5};
String haystack = "hello,world";
String needle = "world";
int len = removeDuplicates(nums, haystack, needle);
System.out.println(len); // 7

以上就是本次完整攻略的全部内容,希望对您有所帮助。

阅读剩余 67%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java算法入门之有效的括号删除有序数组中的重复项实现strStr - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • java Struts2 在拦截器里的跳转问题

    针对“java Struts2 在拦截器里的跳转问题”的完整攻略,我来逐步讲解及演示示例。 1. Struts2 拦截器介绍 Struts2 是一个由 Apache 组织推出的开源的 JavaEE Web 应用框架。在构建应用时,Struts2 利用了一种称为拦截器(Interceptor) 的机制,以实现动态地改变应用程序处理请求的流程。简单来说,拦截器是…

    Java 2023年5月19日
    00
  • 如何实现线程安全的锁?

    以下是关于如何实现线程安全的锁的完整使用攻略: 什么是线程安全的锁? 线程安全的是指在多线程环下,证多个线程对共享资源的访问有序,避免出现数据不一致或程序崩溃等。在多线程编程中,线程安全的锁是非常重要的,为多个线程同时访问共享资源,会出现程间争用的问题,导致数据不一致或程序崩溃。 如何实现线程安的锁? 为了实现线程安的锁,需要使用同步机来保证多个线程对共享资…

    Java 2023年5月12日
    00
  • JavaScript解析JSON数据示例

    下面是关于“JavaScript解析JSON数据示例”的完整攻略。 什么是JSON数据格式 JSON指的是JavaScript对象表示法(JavaScript Object Notation),它是一种轻量级的数据交换格式。它易于人们阅读和编写,同时也易于机器解析和生成。在很多网站中,JSON已成为主流的数据格式之一。 具体来说,JSON数据格式是由一系列键…

    Java 2023年5月26日
    00
  • 通过反射实现Java下的委托机制代码详解

    先来了解一下反射和委托机制。 反射是Java语言的一种特性,它可以让我们在程序运行时动态地获取和操作类的信息。而委托机制则是一种实现面向对象编程的方法,它将任务的具体实现委托给其他对象来完成。在实际场景中,我们常常通过反射来动态地绑定委托关系,实现更加灵活和智能的程序设计。 下面就来详细讲解如何通过反射实现Java下的委托机制。 步骤一:定义一个接口 首先,…

    Java 2023年5月23日
    00
  • Java精品项目瑞吉外卖之登陆的完善与退出功能篇

    Java精品项目瑞吉外卖之登陆的完善与退出功能篇 概述 本教程旨在介绍Java精品项目瑞吉外卖中登陆的完善与退出功能的实现,包括登陆功能的实现,退出功能的实现以及必要的测试。 登陆功能的实现 1. 前端页面设计 登陆页面需要设计一个表单,包含账号和密码两个输入框,以及一个登陆按钮,具体代码如下: <form> <label for=&quo…

    Java 2023年5月24日
    00
  • 这一次搞懂Spring的Bean实例化原理操作

    这一次搞懂Spring的Bean实例化原理操作 简介 在Spring中,Bean是个非常核心且重要的概念,了解Bean的实例化原理对于我们理解Spring框架的工作原理至关重要。本文将详细讲解Spring的Bean实例化过程及其相关细节。 Bean实例化原理 在Spring中,Bean的实例化主要分为以下两个步骤: 定位Bean定义文件并读取Bean定义信息…

    Java 2023年5月26日
    00
  • Java创建文件且写入内容的方法

    下面是”Java创建文件且写入内容的方法”的完整攻略: 前置知识 在学习Java创建文件且写入内容的方法之前,需要先了解Java中文件和流的概念。在Java中,操作文件需要使用File类,而读写文件需要使用输入输出流。 创建文件 Java中创建文件可以使用File类的createNewFile()方法: File file = new File("…

    Java 2023年5月20日
    00
  • Java经典排序算法之插入排序

    Java经典排序算法之插入排序 插入排序算法简介 插入排序是一种简单直观的排序算法,它的基本思想是将待排序序列分为已排序和未排序两部分,初始时将第一个元素视为已排序序列,将其他元素视为未排序序列。然后依次将未排序序列中的元素插入到已排序序列中的正确位置。在插入元素时,需要从右到左比较已排序序列中的元素,找到插入元素的正确位置。 插入排序算法示例 假设我们要对…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部