leetcode刷题26 删除排序数组中的重复项 Remove Duplicates from Sorted Array(简单) Python Java

博客围绕排序数组原地去重问题展开,要求在不使用额外数组空间、O(1) 额外空间条件下,原地删除重复元素并返回新长度。给出两个示例,还说明了返回值与输出答案形式的问题,最后提及两种解法,包括 Java 版本。

题目:

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。


示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。


说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

解法一:

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:  # 判断是否为空数组
            return 0

        start = 0  # 新数组下标
        for i in range(1, len(nums)):
            if nums[i] != nums[start]:
                start += 1
                nums[start] = nums[i]
        return start + 1

if __name__ == '__main__':
    a = Solution()
    result = a.removeDuplicates([1,2,2,3,3,3,4])
    print(result)

结果为4

 

解法二:

class Solution:
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        pe: int
        """
        i=0
        while i<len(nums)-1:
            if nums[i]==nums[i+1]:  # 如果元素相同则从数组中移除
                nums.remove(nums[i])
            else:
                i=i+1  # 元素不同则数组下标加一
        return len(nums)

if __name__ == '__main__':
    a = Solution()
    result = a.removeDuplicates([1,2,2,3,3,3,4])
    print(result)

 

以下是Java版本:

/**
 * 移除有序数组中的重复元素:
 *    给定一个排序的数组,将数组中的重复元素去掉,相同的只保留一个,并且返回数组新的元素个数,
 *    不要创建一个新的数组来保存结果。
 *    
 * 做法是维护两个指针,一个保留当前有效元素的长度,一个从前往后扫,然后跳过那些重复的元素。
 * 因为数组是有序的,所以重复元素一定相邻,不需要额外记录。
 * 时间复杂度是O(n),空间复杂度O(1)。
*/
public class RemoveDuplicates {
	 public int removeDuplicates(int[] nums) {
	        if(nums == null || nums.length==0)  
	        return 0;  
	    int index = 1;  
	    for(int i=1;i<nums.length;i++) {  
	        if(nums[i]!=nums[i-1]){  
	            nums[index]=nums[i];  
	            index++;  
	        }  
	    }  
	    return index;  
       }
}

 

C# 中,事件Event)是用于实现发布-订阅模式的核心机制之一,广泛用于处理异步编程、用户界面交互以及组件通信等场景。事件允许一个对象在某些状态发生变化时通知其他对象,而无需知道这些对象的具体实现。 ### 事件的基本概念 事件是基于委托(Delegate)的封装。委托定义了事件的签名,即事件发生时调用的方法的参数和返回类型。事件可以被订阅(使用 `+=` 操作符),也可以被取消订阅(使用 `-=` 操作符)。 ### 定义和使用事件 以下是一个简单的 C# 事件示例: ```csharp using System; public class EventPublisher { // 定义一个委托 public delegate void NotifyEventHandler(string message); // 定义一个事件 public event NotifyEventHandler Notify; // 触发事件的方法 public void RaiseEvent(string message) { Notify?.Invoke(message); } } public class EventSubscriber { public void OnNotify(string message) { Console.WriteLine($"Received notification: {message}"); } } class Program { static void Main() { EventPublisher publisher = new EventPublisher(); EventSubscriber subscriber = new EventSubscriber(); // 订阅事件 publisher.Notify += subscriber.OnNotify; // 触发事件 publisher.RaiseEvent("Hello, World!"); } } ``` 在这个例子中,`EventPublisher` 类定义了一个名为 `Notify` 的事件,`EventSubscriber` 类包含一个方法 `OnNotify`,该方法被注册为事件的处理程序。当 `RaiseEvent` 方法被调用时,所有订阅该事件的方法都会被触发。 ### 多播事件处理 C#事件支持多播,即一个事件可以绑定多个处理方法。这些方法会按照它们被添加的顺序依次执行。 ```csharp publisher.Notify += subscriber.OnNotify; publisher.Notify += (message) => Console.WriteLine($"Another handler: {message}"); publisher.RaiseEvent("Multi-cast event"); ``` ### 使用 `EventHandler` 和 `EventArgs` 在实际开发中,通常使用 .NET 提供的 `EventHandler` 和 `EventArgs` 类来定义事件。`EventArgs` 可以携带事件发生时的附加信息。 ```csharp public class CustomEventArgs : EventArgs { public string Message { get; set; } } public class EventPublisher { public event EventHandler<CustomEventArgs> CustomEvent; public void RaiseCustomEvent() { CustomEvent?.Invoke(this, new CustomEventArgs { Message = "Custom event raised." }); } } class Program { static void Main() { EventPublisher publisher = new EventPublisher(); publisher.CustomEvent += (sender, e) => { Console.WriteLine($"Custom event received: {e.Message}"); }; publisher.RaiseCustomEvent(); } } ``` ### 事件与线程安全 在多线程环境中,事件的订阅和触发需要考虑线程安全。通常可以使用锁(`lock`)或 `Interlocked` 类来确保线程安全的操作。 ```csharp private object lockObj = new object(); public void SafeRaiseEvent(string message) { lock (lockObj) { Notify?.Invoke(message); } } ``` ### 事件在实际开发中的应用 事件广泛应用于 GUI 编程(如 WPF、WinForms)、异步编程(如 `async/await`)、以及各种组件之间的通信。例如,在 WPF 中,按钮点击事件是通过事件机制实现的: ```csharp button.Click += (sender, e) => { MessageBox.Show("Button clicked!"); }; ``` ### 相关问题 1. C# 中委托和事件的区别是什么? 2. 如何在 C# 中实现线程安全的事件处理? 3. C# 中如何使用 `EventHandler` 和 `EventArgs`? 4. C# 事件如何支持多播?如何控制事件处理的顺序? 5. 在 WPF 或 WinForms 中,事件是如何与 UI 交互的?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值