在复杂度为O(n)和时间为O(1)的数组中旋转左侧元素

时间:2017-05-27 14:55:48

标签: objective-c algorithm data-structures big-o

我正在尝试解决将数组内部旋转到左侧的问题。示例:array = [1,2,3,4,5,6,7]如果我调用函数rotateToLeft(array[],int numberElements,int count),其中:array是要旋转的数组,numberElements是要向左旋转的元素数量count是数组的大小。我正在寻找O(n)复杂度和O(1)耗时的算法。我的第一个解决方案是使用双向链表,但我想知道是否有更好的解决方案。

链表的类节点

    @interface Node : NSObject

    @property (nonatomic,assign) int element;
    @property (nonatomic,strong) Node* next;
    @property (nonatomic,strong) Node* previous;

    @end

管理链表的类

    @interface LinkedList : NSObject
    @property (nonatomic,strong) Node* tail;
    @property (nonatomic,strong) Node* root;

   -(void)addNode:(int)value;
   -(void)printList;
   -(void)rotateLeftElementsOnList:(LinkedList*)list elements:(int)numElement;

   @end

   @implementation LinkedList

    -(instancetype)init{
        self = [super init];
        if (self) {
            self.tail = nil;
        }
        return self;

    }

    -(void)addNode:(int)value{
        Node* newNode = [[Node alloc] init];
        newNode.element = value;
        newNode.previous = nil;
        newNode.next = nil;
        if (self.tail == nil) {
            newNode.next = nil;
            newNode.previous = nil;
            self.tail = newNode;
            self.root = newNode;
            return;

        }
        self.tail.previous = newNode;
        newNode.next = self.tail;
        self.tail = newNode;   
    }

    -(void)printList{
        Node* header = self.root;
        while(header.previous != nil){
            NSLog(@"%d",header.element);
            header = header.previous;

        }
        NSLog(@"%d",header.element);
    }

/////这是我旋转元素的功能,但是我想知道是否有人知道更好的解决方案,

    -(void)rotateLeftElementsOnList:(LinkedList*)list elements:(int)numElement{
        Node* header = self.root;
        int index = 0;
        while(index < numElement){
        header = header.previous;
        index++;

    }
        header.next.previous = nil;
        header.next = nil;
        self.root.next = self.tail;
        self.tail.previous = self.root;
        self.root = header;

    }

3 个答案:

答案 0 :(得分:2)

链表是数组的O(n)导数。这就是这个想法的底线。如果您正好转换为列表,请转换为一个环,并将最后一个节点的下一个指针指向头部。跟踪头指针。这样,只需前进头指针就可以完成移位。

答案 1 :(得分:1)

我不知道objective-c,所以我不能为你提供代码。但这是一个想法。您可以创建一个类,而不是移动数组,该类将具有2个属性:类型为a的{​​{1}}和类型为list/array的{​​{1}}。之后,您将获得方法shift,该方法将使用int值获取get_element(int i)元素。伪代码看起来像这样:

i-th

答案 2 :(得分:1)

我不了解Objective-C,所以不幸的是,我无法为您提供代码段;但我会向你解释逻辑:

  1. 反转第一个count个元素数量;
  2. 反转其余元素;
  3. 现在反转整个阵列。
  4. 实施例: 数组是:[1 2 3 4 5 6 7 8],你想转移3个地方:

    1. 第1步:[3 2 1 4 5 6 7 8]
    2. 第2步:[3 2 1 8 7 6 5 4]
    3. 第3步:[4 5 6 7 8 1 2 3]
    4. 时间复杂度为O(n),因为您只是遍历元素一次以反转它们,并且空间复杂度为O(1),因为您没有使用任何额外的辅助存储空间。希望这有用!