精华内容
下载资源
问答
  • 删除一个元素变成有序
    千次阅读
    2020-09-27 22:36:14

    思想:

    直接插入排序算法

    代码:

    void sort(LinkList * &L){
    	LinkList *p,*pre,*r;
    	p = L->next->next;		// 先保存下L的第二个元素,因为下一步要将L变成只有一个元素的有序表; p指针用来遍历无序区 
    	L->next->next = NULL;	// 将L变成只有一个元素的有序表
    	// 从L的第二个元素开始遍历整个L直至表尾 
    	while(p != NULL){
    		r = p->next; 
    		pre = L;	// 先用pre来保存L,pre始终指向有序区
    		while(pre->next !=NULL && p->data > pre->next->data) // 遍历pre所指向的有序表L,直至找到比p大的节点 
    			pre = pre->next; 
    		p->next = pre->next;//将p插到pre之后,头插法 
    		pre->next = p;
    		p = r;	
    	} 
    }
    

     

    更多相关内容
  • 在工作中的许多场景下,我们都会使用到List这个数据结构,那么同样的有很多场景下需要删除List中的某一个元素或某几个元素,那么我们该如何正确无误地删除List中的元素的,今天我来教大家三种方式。前提知识准备for...

    在工作中的许多场景下,我们都会使用到List这个数据结构,那么同样的有很多场景下需要删除List中的某一个元素或某几个元素,那么我们该如何正确无误地删除List中的元素的,今天我来教大家三种方式。

    前提知识准备

    for循环的执行顺序

    这里借用百度百科的一张图,简明扼要的介绍一下

    146c04f8c5bc84b13f13df89e4d8f12b.png

    Iterator介绍

    迭代器:迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式。Iterator 模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向每次遍历前都需要知道要遍历集合的内部结构。

    // 遍历list

    List list = new ArrayList();

    list.add(1);

    list.add(2);

    for (int i = 0; i < list.size(); i++) {

    Object object = list.get(i);

    // do something

    }

    // 遍历map

    Map map = new HashMap<>();

    map.put("1","first");

    map.put("2","second");

    for (Map.Entry entry : map.entrySet()){

    String key = entry.getKey();

    String value = entry.getValue();

    // do something

    }

    对于这两种方式,我们总是都事先知道集合的内部结构,访问代码和集合本身是紧密耦合的,无法将访问逻辑从集合类和遍历方法中分离出来。同时每一种集合对应一种遍历方法,代码无法复用。

    为了解决以上问题, Iterator 模式腾空出世,它总是用同一种逻辑来遍历集合。使得需要遍历集合的人,在遍历的时候不需要了解集合的内部结构,所有的内部状态都由 Iterator 来维护。遍历集合的方法不直接和集合类打交道,它总是控制 Iterator,向它发送”向前”,”向后”,”取当前元素”的命令,就可以间接遍历整个集合。

    两种错误的方式

    for循环顺序遍历

    直接使用简单for循环,以for (int i = 0; i < list.size(); i++) 进行遍历,这种方式可能会在遍历的过程中漏掉部分元素,从而出现少删的情况。

    /**

    * 通过简单的遍历方式,在遍历的过程中有可能会漏掉元素

    * 取第二个元素i=1时,满足条件被删掉,原有的数组的第三个元素,变成了新数组的第二个元素

    * i++后i=2,但i=2指向的是新数组中的第三个元素,那么原数组中的第三个元素就被漏掉了

    *

    * @param list

    * @param element

    * @return

    */

    public static List forRemove(List list, Object element) {

    for (int i = 0; i < list.size(); i++) {

    if (element.equals(list.get(i))) {

    list.remove(i);

    }

    }

    return list;

    }

    增强for循环,删除后不退出

    使用增强for循环是,如果删除后继续向下循环则会报java.util.ConcurrentModificationException

    /**

    * 使用增强for循环是,如果删除后继续向下循环则会报

    * java.util.ConcurrentModificationException

    *

    * @param list

    * @param element

    * @return

    */

    public static List forceForRemove(List list, Object element) {

    for (Object item : list) {

    if (item.equals(element)) {

    list.remove(item);

    }

    }

    return list;

    }

    异常如下:

    Exception in thread "main" java.util.ConcurrentModificationException

    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)

    at java.util.ArrayList$Itr.next(ArrayList.java:851)

    at com.lingyejun.leetcode.RemoveListElement.forceForRemove(RemoveListElement.java:57)

    at com.lingyejun.leetcode.RemoveListElement.main(RemoveListElement.java:112)

    三种正确方式

    逆向循环遍历

    我们使用逆向遍历的方式可以得到正确的结果

    /**

    * 逆向循环,是正确的

    * 1-->2-->3-->4

    * 逆向循环时,倒数第一个元素满足条件被删除时,i--后,原数组的倒数第二个变成了新数组的倒数第一个元素

    * i = size-2指向新数组的最后一个元素,没有漏掉。

    * 同理倒数第二个元素满足条件被删除时,i--后,原数组的倒数第三个变成了新数组的倒数第二个元素

    * i= size-3指向新数组的倒数第二个元素,也没有漏掉

    *

    * @param list

    * @param element

    * @return

    */

    public static List reverseorRemove(List list, Object element) {

    for (int i = list.size() - 1; i >= 0; i--) {

    if (element.equals(list.get(i))) {

    list.remove(i);

    }

    }

    return list;

    }

    增强for循环删除元素后break

    使用增强for循环,删除元素后,立即跳出,则正常退出,但缺点是不能向后继续循环了。

    /**

    * 删除元素后,立即跳出,则正常退出,但不能向后继续循环了

    *

    * @param list

    * @param element

    * @return

    */

    public static List forceForRemove1(List list, Object element) {

    for (Object item : list) {

    if (item.equals(element)) {

    // 删除后立马终端循环,会正常跳出,但代价是不能继续向后循环了

    list.remove(item);

    break;

    }

    }

    return list;

    }

    使用Iterator迭代器

    使用迭代器可,正确无误的删除,代码简洁优雅,推荐使用!

    /**

    * 使用迭代器可,正确无误的删除

    *

    * @param list

    * @param element

    * @return

    */

    public static List iteratorRemove(List list, Object element) {

    Iterator iterator = list.iterator();

    while (iterator.hasNext()) {

    Object cur = iterator.next();

    if (cur.equals(element)) {

    // 注意!!!这里时Iterator.remove()!!!而不是list.remove()!!!

    iterator.remove();

    }

    }

    return list;

    }

    展开全文
  • 给你一个下标从 0 开始的整数数组 nums ,如果 恰好 删除 一个 元素后,数组 严格递增 ,那么请你返回 true ,否则返回 false 。如果数组本身已经是严格递增的,请你也返回 true 。 数组 nums 是 严格递增 的定义为...

    题目

    给你一个下标从 0 开始的整数数组 nums ,如果 恰好 删除 一个 元素后,数组 严格递增 ,那么请你返回 true ,否则返回 false 。如果数组本身已经是严格递增的,请你也返回 true 。
    数组 nums 是 严格递增 的定义为:对于任意下标的 1 <= i < nums.length 都满足 nums[i - 1] < nums[i] 。
    示例 1:
    输入:nums = [1,2,10,5,7]
    输出:true
    解释:从 nums 中删除下标 2 处的 10 ,得到 [1,2,5,7] 。
    [1,2,5,7] 是严格递增的,所以返回 true 。
    示例 2:
    输入:nums = [2,3,1,2]
    输出:false
    解释:
    [3,1,2] 是删除下标 0 处元素后得到的结果。
    [2,1,2] 是删除下标 1 处元素后得到的结果。
    [2,3,2] 是删除下标 2 处元素后得到的结果。
    [2,3,1] 是删除下标 3 处元素后得到的结果。
    没有任何结果数组是严格递增的,所以返回 false 。
    示例 3:
    输入:nums = [1,1,1]
    输出:false
    解释:删除任意元素后的结果都是 [1,1] 。
    [1,1] 不是严格递增的,所以返回 false 。
    示例 4:
    输入:nums = [1,2,3]
    输出:true
    解释:[1,2,3] 已经是严格递增的,所以返回 true 。
    提示:
    2 <= nums.length <= 1000
    1 <= nums[i] <= 1000
    来源:力扣(LeetCode)

    解题思路

      一个简单的方向就是先遍历数组,找到数组中元素不符合严格递增的点,然后通过分析情况修改数组,当然只能进行一次删除操作,最后再来一轮判断。

    class Solution:
        def canBeIncreasing(self, nums: List[int]) -> bool:
            i=1
            n=len(nums)
            while i<len(nums):
                if nums[i]>nums[i-1]:
                    i+=1
                else:  #如果当前点使得数组不是严格单增
                    if i-2>=0:  #检查当前元素前面的第二个点
                        if nums[i]>nums[i-2]: #如果当前点和前面第二个点构成严格递增,则删除当前元素前面第一个点
                            del nums[i-1]
                        else:  #否则删除当前元素
                            del nums[i]
                    else:  #如果前面只有一个元素,那么删除当前点即可
                        del nums[i-1]
                    break
            if n==len(nums):  #没有发生删除,原数组严格单增
                return True
            for i in range(1,len(nums)): #进行一次删除操作后是否是严格单增
                if nums[i]<=nums[i-1]:
                    return False
            return True
    

    在这里插入图片描述

    展开全文
  • 删除有序链表中重复的元素ⅠⅡ

    删除有序链表中重复的元素-I

    描述
    删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次
    例如:
    给出的链表为1→1→2,返回1→2.
    给出的链表为1→1→2→3→3,返回1→2→3.
    数据范围:链表长度满足 0≤n≤100,链表中任意节点的值满足∣val∣≤100
    进阶:空间复杂度 O(1),时间复杂度 O(n)
    示例1
    输入:{1,1,2}
    返回值:{1,2}
    示例2
    输入:{}
    返回值:{}
    思路
    为了符合链表的特性,比较当前节点和他的下一个节点,对于重复的情况将他的下一个节点删除
    代码

    public ListNode deleteDuplicates (ListNode head) {
            // write code here
            ListNode cur = head;
            while(cur!=null && cur.next!=null){
                if(cur.val == cur.next.val){
                    cur.next = cur.next.next;
                    //这里cur不需要变,为了防止多个值连续相同的情况
                }
                else{
                    cur = cur.next;
                }
            }
            return head;
        }
    

    删除有序链表中重复的元素-II

    描述
    给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
    例如:
    给出的链表为1→2→3→3→4→4→5, 返回1→2→5.
    给出的链表为1→1→1→2→3, 返回2→3.
    数据范围:链表长度0≤n≤10000,链表中的值满足∣val∣≤1000
    要求:空间复杂度 O(n),时间复杂度 O(n)
    进阶:空间复杂度 O(1),时间复杂度 O(n)
    示例1
    输入:{1,2,2}
    返回值:{1}
    示例2
    输入:{}
    返回值:{}
    思路
    针对上一问题需要考虑的情况更多了,比如头结点可能被删除,以及之前的方法无法删除重复部分的第一个节点,因此需要一种更进一步的算法
    具体的解决方法有很多,比如维护一个num记录当前判断的数,若有重复就把所有的重复节点删除。
    我采用了一种自己设计的方法,为防止第一个节点被删除,引入一个dummy节点。
    需维护四个值:
    cur:可看成是比较部分的前一节点,即pre
    cur.next:可看成第一个被比较节点
    cur.next.next:可看成第一个被比较节点
    flag:是否删除重复部分的第一个值
    具体流程如下,每次比较cur.next和cur.next.next,若相等,flag置为1,删除cur.next.next,循环比较直到所有重复值删除完成,删除掉cur.next,flag置为0
    为了防止有删除到最后cur.next.next变成空的情况,在退出while循环后再判断一遍flag是否为1,若为1,删除掉cur.next

    public ListNode deleteDuplicates (ListNode head) {
            ListNode dummy = new ListNode(-1);
            dummy.next = head;
            ListNode cur = dummy;
            int flag=0;
            while(cur!=null && cur.next!=null && cur.next.next!=null){
                if(cur.next.val == cur.next.next.val){
                    flag=1;
                    cur.next.next = cur.next.next.next;
                }
                else{
                    if(flag==1){
                        cur.next = cur.next.next;
                        flag = 0;
                    }
                    else{
                        cur = cur.next;
                    }
                }
            }
            if(flag==1){//最后再判断一遍有没有重复部分的第一个节点未删除
                cur.next = cur.next.next;
            }
            return dummy.next;
        }
    
    展开全文
  • 题目:在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素,如(7,10,10,21,30,42,42,42,51,70)将其变为(7,10,21,30,42,51,70)。 算法思想:...
  • 一个递增非空单链表,设计一个算法删除值域重复的结点。例如,{1,1,2,3,3,3,4,4,7,7,7,9,9,9}经过删除变成{1,2,3,4,7,9}。 #include<iostream> using namespace std; //考试时不用写...
  • 一个长度不超过10000数据的顺序表,可能存在着一些值相同的“多余”数据元素(类型为整型),编写一个程序将“多余”的数据元素从顺序表中删除,使该表由一个“非纯表”(值相同的元素在表中可能有多个)变成一个...
  • 一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法,去掉数值相同的元素,使得表中不再有重复的元素。例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51,...
  • #include <stdio.h> #define maxlen 30 ... //存放顺序表中元素个数 } sqlisttp; void demo(sqlisttp* L) { int i = 1, j = 0; while (i<L->lenth) { if (L->elem[i] != L->elem[j])...
  • 基于此,初始时,将第一个元素看做是非重复的有序表,之后依次判断后面的元素是否与前面非重复有序表的最后一个元素相同,若相同则继续向后判断,不相同则插入到前面的非重复有序表的最后,直至判断结束为止。...
  • 【数据结构】 合并两个非递减有序单链表为一个A-B的非递减有序单链表 题目 实现两个单链表La和Lb的相减链表LC,LC的元素为LA中有但LB中没有的元素。LA和LB都为非递减有序链表 分析 LC是LA和LA的相减链表,即LC= ...
  • 如题,求指导!
  • 循环比较两个有序数组头位元素的大小,并把头元素放到新数组中,从老数组中删掉,直到其中一个数组长度为0。然后再把不为空的老数组中剩下的部分加到新数组的结尾。 第二种思路的排序算法与测试代码如下: def merge...
  • Codeup问题 F: 算法2-25 有序单链表删除重复元素 题目地址 ...根据一个递增的整数序列构造有序单链表,删除其中的重复元素 输入 输入包括多组测试数据,每组测试数据占一行,第一个为大于等...
  • 思路分析:首先对序列进行排序,接着定义一个指向序列头的指针,逐次向后... * 去重规则:重复元素的第一个删除,第二个倍乘 * 说明:可以使用Arrays.asList(...)将数组转为List; * @param lists 无序序列 * @retu
  • 题目:在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素,例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51...
  • 我可以想到一个简单的循环方法来实现这一点,但这将是非常低效的。做这件事的方法是什么?例如,如果我有l1 = [1,2,6,8] and l2 = [2,3,5,8],l1 - l2应该返回[1,6]。只是一个提示:pep8声明不应该使用小写"l",因为...
  • 删除有序数组中重复项的k次扩展
  • 给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 说明: 为什么...
  • 题目描述给定一个已排序的数组,去除数组中的重复元素,只保留一个重复的元素,并且返回新的数组长度。要求:不要给数组分配额外的空间,你必须使用常量的内存大小进行原地操作。例如:给出数组A=[1,1,2],你的函数...
  • //p指向开始结点,q指向头结点 while(p&&p->data>a) //从前向后遍历递减序列,在第一个小于a的位置上插入 { p=p->next; q=q->next; //大于a时,则移动p和q指针,q是p的前驱结点 } if(q->next==p) { s=(LinkList...
  • 对于数组来说,在尾部插⼊、删除元素是⽐较⾼效的,时间复杂度是 O(1),但是如果在中间或者开头插⼊、删除元素,就会涉及数据的搬移,时间复杂度为 O(N),效率较低。 所以对于⼀般处理数组的算法问题,我们要尽可能...
  • 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下
  • 对于一个有序数组,如果要查找其中的一个数,我们可以使用二分查找(Binary Search)算法,将它的时间复杂度降低为O(logn).那查找一个有序链表,有没有办法将其时间复杂度也降低为O(logn)呢? 跳表(skip list),全称为...
  • 如果数组中元素最多允许重复两次呢? 例如: 给出有序数组 A =[1,1,1,2,2,3], 你给出的函数应该返回length =5, A 变为[1,1,2,2,3]. 2 解题思路 暴力法 3 代码实现 class Solution { public: int removeDuplicates...
  • //在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素,例如:(7,10,10,21,30,42,42,51,70)将变为(7,10,21,30,42,51,70)...
  • 一个递增有序的线性表中,有数值相同的元素存在.若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素,例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51,70) #include<stdio.h>...
  • 给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,908
精华内容 25,963
热门标签
关键字:

删除一个元素变成有序