137. Single Number II

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?



First think

we record each bits occurrence

for example 2 2 2 3        0010 0010 0010 0011

should be 

0 0 4 1 

and then for each occurrence mod 3   -> 0 0 1 1  and this is the result.


since we do not want to use extra space, we need to use bit to represent the number,

1 bit can represent 0 , 1

2 bit can represent 00 01 10 11 that is from 0 - 3 which is enough since we only need 0 - 2 because i % 3 could only be 0 ,1 or 2


we use two number to store the occurrence, i2 stores the first bot and i1 stores the last bit.

simulating 0010 0010 0010 0011

i2 0 0 0 0

i1 0 0 0 0

when 0010 come 

i2  0 0 0 0

i1  0 0 1 0

when 0010 come 

i2  0 0 1 0

i1  0 0 0 0


when 0010 come 

i2  0 0 1 0

i1  0 0 1 0

and we need to mod 3

i2  0 0 0 0

i1  0 0 0 0


when 0011 come

i2  0 0 0 0

i1  0 0 1 1


return i1

 

by doing the calculation 

if i1[k] ==  n[k]:  newi1[k] = 0, otherwise newi1[k] = i1[k]

newi1 = i1 ^ n

and we need to compute the carry for i2 to add.  if carry[k] == 1 it means i1[k] = 1 && newi1[k] = 0

carry = i1 & (~newi1)

newi2 = carry ^ i2

then we need to mod 3 for each digit, which digit should be change? that newi1 ^ newi2 == 1

int tpminus = newi1 ^ newi2;

i1 =  newi1 -  tominus,    i2 = newi2 - tominus.

return  i1.




code:

public class Solution {
    public int singleNumber(int[] nums) {
        //i2  i1
        int i1 = 0;
        int i2 = 0;
        for(int n : nums){
            int newi1 = i1 ^ n;
            int carry = i1 & (~newi1);
            int newi2 = i2 ^ carry;
            int minus = newi1 & newi2;

            i1 = newi1 - minus;
            i2 = newi2 - minus;
        }
        return i1;
        
    }
}






Sure, here are some common OOP features and principles: Features: 1. Encapsulation: Encapsulation is the process of hiding the implementation details of an object from the outside world, and restricting access to the object's internal data and methods. 2. Abstraction: Abstraction is the process of creating a simplified version of something complex, in order to make it more manageable and easier to understand. 3. Inheritance: Inheritance is the mechanism by which one class inherits properties and methods from another class. 4. Polymorphism: Polymorphism is the ability of an object to take on many different forms, depending on the context in which it is used. Principles: 1. Single Responsibility Principle: The Single Responsibility Principle (SRP) states that a class should have only one reason to change. This means that a class should only be responsible for one thing, and should not be responsible for multiple unrelated tasks. 2. Open/Closed Principle: The Open/Closed Principle (OCP) states that a class should be open for extension but closed for modification. This means that you should be able to add new functionality to a class without modifying its existing code. 3. Liskov Substitution Principle: The Liskov Substitution Principle (LSP) states that a subclass should be able to be substituted for its parent class without affecting the correctness of the program. This means that a subclass should be able to use all the methods and properties of its parent class without any issues. 4. Interface Segregation Principle: The Interface Segregation Principle (ISP) states that a class should not be forced to implement interfaces it does not use. This means that you should only include the methods and properties that are necessary for a class to perform its specific tasks in its interface. 5. Dependency Inversion Principle: The Dependency Inversion Principle (DIP) states that high-level modules should not depend on low-level modules, but both should depend on abstractions. This means that you should use interfaces or abstract classes to decouple the high-level and low-level classes, making your code more flexible and easy to maintain.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值